diff --git a/openclaw_assistant/config.yaml b/openclaw_assistant/config.yaml index 3b99056..f9421ca 100644 --- a/openclaw_assistant/config.yaml +++ b/openclaw_assistant/config.yaml @@ -89,8 +89,13 @@ options: force_ipv4_dns: false # Environment variables to pass to the gateway (semicolon-separated key=value pairs) - # Example: "SERVICE_API=123;SERVICE2_API=1231" - # These will be exported as environment variables when running the gateway + # Format: "KEY1=value1;KEY2=value2" (semicolon-separated, no spaces around '=') + # Examples: + # - API keys: "OPENAI_API_KEY=sk-abc123;ANTHROPIC_API_KEY=claude-key" + # - Service URLs: "SERVICE_URL=https://api.example.com;LOG_LEVEL=debug" + # - Features: "FEATURE_FLAG_X=1;FEATURE_FLAG_Y=0" + # Limits: max 50 variables, max key length 255 chars, max value length 10000 chars + # Note: Values may contain special characters; they are not shell-escaped gateway_env_vars: "" diff --git a/openclaw_assistant/oc_config_helper.py b/openclaw_assistant/oc_config_helper.py index 3bfbd44..aecc798 100644 --- a/openclaw_assistant/oc_config_helper.py +++ b/openclaw_assistant/oc_config_helper.py @@ -12,6 +12,11 @@ from pathlib import Path CONFIG_PATH = Path(os.environ.get("OPENCLAW_CONFIG_PATH", "/config/.openclaw/openclaw.json")) +# Limits for environment variable handling +MAX_ENV_VARS = 50 +MAX_ENV_VAR_NAME_SIZE = 255 +MAX_ENV_VAR_VALUE_SIZE = 10000 + def read_config(): @@ -150,13 +155,37 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a if '=' not in pair: print(f"WARN: Invalid env var format '{pair}' (missing '=')") continue + key, value = pair.split('=', 1) key = key.strip() value = value.strip() + + # Validate key format if not key: print(f"WARN: Invalid env var key (empty)") continue + if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', key): + print(f"WARN: Invalid env var name '{key}' (must start with letter/underscore)") + continue + + # Enforce size limits + if len(key) > MAX_ENV_VAR_NAME_SIZE: + print(f"ERROR: Environment variable name '{key}' too long (max {MAX_ENV_VAR_NAME_SIZE} chars)") + return False + if len(value) > MAX_ENV_VAR_VALUE_SIZE: + print(f"ERROR: Environment variable '{key}' value too large (max {MAX_ENV_VAR_VALUE_SIZE} chars)") + return False + + # Warn about duplicate keys + if key in new_env_vars: + print(f"WARN: Environment variable '{key}' appears multiple times; using last value") + new_env_vars[key] = value + + # Enforce limit on total variables + if len(new_env_vars) > MAX_ENV_VARS: + print(f"ERROR: Too many environment variables ({len(new_env_vars)}), max {MAX_ENV_VARS}") + return False except Exception as e: print(f"ERROR: Failed to parse environment variables: {e}") return False @@ -164,7 +193,8 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a if new_env_vars != current_env_vars: gateway["env"] = new_env_vars if new_env_vars: - changes.append(f"env: {len(new_env_vars)} variables") + var_names = ', '.join(sorted(new_env_vars.keys())) + changes.append(f"env: {var_names}") else: changes.append("env: cleared") diff --git a/openclaw_assistant/run.sh b/openclaw_assistant/run.sh index b9ef6b7..76a4cc0 100644 --- a/openclaw_assistant/run.sh +++ b/openclaw_assistant/run.sh @@ -152,21 +152,46 @@ export PATH="${PNPM_HOME}:${PATH}" # These are user-defined variables that should be available to the gateway process if [ -n "$GW_ENV_VARS" ]; then echo "INFO: Setting gateway environment variables from add-on config..." - IFS=';' read -ra ENV_VARS <<< "$GW_ENV_VARS" - for var in "${ENV_VARS[@]}"; do - var=$(echo "$var" | xargs) # trim whitespace - if [ -z "$var" ]; then + env_count=0 + max_env_vars=50 + max_var_name_size=255 + + while IFS='=' read -r key value; do + # Skip empty lines + if [ -z "$key" ]; then continue fi - if [[ ! "$var" =~ ^[A-Za-z_][A-Za-z0-9_]*=.*$ ]]; then - echo "WARN: Invalid environment variable format: '$var' (skipping)" + + # Trim whitespace + key=$(echo "$key" | xargs) + value=$(echo "$value" | xargs) + + # Validate variable name format + if ! [[ "$key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then + echo "WARN: Invalid environment variable name: '$key' (must start with letter/underscore, skip)" continue fi - export "$var" - # Extract key for logging (don't log values for security) - key="${var%%=*}" + + # Enforce max variable name length + if [ ${#key} -gt $max_var_name_size ]; then + echo "WARN: Environment variable name too long: '$key' (max $max_var_name_size chars, skip)" + continue + fi + + # Enforce limit on number of variables + if [ $env_count -ge $max_env_vars ]; then + echo "WARN: Maximum environment variables limit ($max_env_vars) reached (skip)" + continue + fi + + export "$key=$value" + ((env_count++)) echo "INFO: Exported gateway env var: $key" - done + done < <(echo "$GW_ENV_VARS" | tr ';' '\n') + + if [ $env_count -gt 0 ]; then + echo "INFO: Successfully exported $env_count gateway environment variable(s)" + fi fi # ------------------------------------------------------------------------------