mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-20 01:11:18 +00:00
fix: Eliminate heredoc injection, eval, and API key exposure (#108)
- Replace unquoted heredocs with printf + json_escape for all JSON config files containing credentials (8 cloud providers + shared lib) - Replace eval with printf -v for safe indirect variable assignment - Move RunPod API key from URL query param to api-key header Fixes #104, Fixes #105, Fixes #106 Co-authored-by: A <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c0a840ec3a
commit
a24dc101e3
9 changed files with 14 additions and 94 deletions
|
|
@ -81,11 +81,7 @@ ensure_binarylane_token() {
|
|||
return 1
|
||||
fi
|
||||
mkdir -p "$config_dir"
|
||||
cat > "$config_file" << EOF
|
||||
{
|
||||
"api_token": "$api_token"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "api_token": "%s"\n}\n' "$(json_escape "$api_token")" > "$config_file"
|
||||
chmod 600 "$config_file"
|
||||
log_info "API token saved to $config_file"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,11 +74,7 @@ _save_fly_token() {
|
|||
local config_dir="$HOME/.config/spawn"
|
||||
local config_file="$config_dir/fly.json"
|
||||
mkdir -p "$config_dir"
|
||||
cat > "$config_file" << EOF
|
||||
{
|
||||
"token": "$token"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "token": "%s"\n}\n' "$(json_escape "$token")" > "$config_file"
|
||||
chmod 600 "$config_file"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,26 +58,7 @@ GATEWAY_TOKEN=$(openssl rand -hex 16)
|
|||
|
||||
OPENCLAW_CONFIG_TEMP=$(mktemp)
|
||||
chmod 600 "$OPENCLAW_CONFIG_TEMP"
|
||||
cat > "$OPENCLAW_CONFIG_TEMP" << EOF
|
||||
{
|
||||
"env": {
|
||||
"OPENROUTER_API_KEY": "${OPENROUTER_API_KEY}"
|
||||
},
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"auth": {
|
||||
"token": "${GATEWAY_TOKEN}"
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "openrouter/${MODEL_ID}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
printf '{\n "env": {\n "OPENROUTER_API_KEY": "%s"\n },\n "gateway": {\n "mode": "local",\n "auth": {\n "token": "%s"\n }\n },\n "agents": {\n "defaults": {\n "model": {\n "primary": "openrouter/%s"\n }\n }\n }\n}\n' "$(json_escape "${OPENROUTER_API_KEY}")" "$(json_escape "${GATEWAY_TOKEN}")" "$(json_escape "${MODEL_ID}")" > "$OPENCLAW_CONFIG_TEMP"
|
||||
|
||||
upload_file "$OPENCLAW_CONFIG_TEMP" "/root/.openclaw/openclaw.json"
|
||||
rm "$OPENCLAW_CONFIG_TEMP"
|
||||
|
|
|
|||
|
|
@ -159,12 +159,7 @@ print(d.get('api_secret', ''))
|
|||
log_info "API credentials validated"
|
||||
|
||||
mkdir -p "$config_dir"
|
||||
cat > "$config_file" << EOF
|
||||
{
|
||||
"api_client_id": "$client_id",
|
||||
"api_secret": "$secret"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "api_client_id": "%s",\n "api_secret": "%s"\n}\n' "$(json_escape "$client_id")" "$(json_escape "$secret")" > "$config_file"
|
||||
chmod 600 "$config_file"
|
||||
log_info "API credentials saved to $config_file"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,14 +170,9 @@ for k in ('application_key','application_secret','consumer_key','project_id'):
|
|||
local config_dir
|
||||
config_dir=$(dirname "${config_file}")
|
||||
mkdir -p "${config_dir}"
|
||||
cat > "${config_file}" << EOF
|
||||
{
|
||||
"application_key": "${app_key}",
|
||||
"application_secret": "${app_secret}",
|
||||
"consumer_key": "${consumer_key}",
|
||||
"project_id": "${project_id}"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "application_key": "%s",\n "application_secret": "%s",\n "consumer_key": "%s",\n "project_id": "%s"\n}\n' \
|
||||
"$(json_escape "${app_key}")" "$(json_escape "${app_secret}")" \
|
||||
"$(json_escape "${consumer_key}")" "$(json_escape "${project_id}")" > "${config_file}"
|
||||
chmod 600 "${config_file}"
|
||||
log_info "OVHcloud credentials saved to ${config_file}"
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -108,11 +108,7 @@ ensure_railway_token() {
|
|||
# Save to config file
|
||||
export RAILWAY_TOKEN="$token"
|
||||
mkdir -p "$config_dir"
|
||||
cat > "$config_file" << EOF
|
||||
{
|
||||
"token": "$token"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "token": "%s"\n}\n' "$(json_escape "$token")" > "$config_file"
|
||||
chmod 600 "$config_file"
|
||||
log_info "Token saved to $config_file"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ print(json.dumps({'query': q}))
|
|||
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
"${RUNPOD_GRAPHQL_URL}?api_key=${RUNPOD_API_KEY}" \
|
||||
-H "api-key: ${RUNPOD_API_KEY}" \
|
||||
"${RUNPOD_GRAPHQL_URL}" \
|
||||
-d "${body}"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -992,7 +992,7 @@ _update_retry_interval() {
|
|||
current_interval="${max_interval}"
|
||||
fi
|
||||
|
||||
eval "${interval_var}=${current_interval}"
|
||||
printf -v "${interval_var}" '%s' "${current_interval}"
|
||||
}
|
||||
|
||||
# Helper to extract HTTP status code and response body from curl output
|
||||
|
|
@ -1520,22 +1520,7 @@ setup_claude_code_config() {
|
|||
|
||||
# Create settings.json
|
||||
local settings_json
|
||||
settings_json=$(cat << EOF
|
||||
{
|
||||
"theme": "dark",
|
||||
"editor": "vim",
|
||||
"env": {
|
||||
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
|
||||
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
|
||||
"ANTHROPIC_AUTH_TOKEN": "${openrouter_key}"
|
||||
},
|
||||
"permissions": {
|
||||
"defaultMode": "bypassPermissions",
|
||||
"dangerouslySkipPermissions": true
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
settings_json=$(printf '{\n "theme": "dark",\n "editor": "vim",\n "env": {\n "CLAUDE_CODE_ENABLE_TELEMETRY": "0",\n "ANTHROPIC_BASE_URL": "https://openrouter.ai/api",\n "ANTHROPIC_AUTH_TOKEN": "%s"\n },\n "permissions": {\n "defaultMode": "bypassPermissions",\n "dangerouslySkipPermissions": true\n }\n}\n' "$(json_escape "${openrouter_key}")")
|
||||
upload_config_file "${upload_callback}" "${run_callback}" "${settings_json}" "~/.claude/settings.json"
|
||||
|
||||
# Create .claude.json global state
|
||||
|
|
@ -1593,27 +1578,7 @@ setup_openclaw_config() {
|
|||
|
||||
# Create openclaw.json config
|
||||
local openclaw_json
|
||||
openclaw_json=$(cat << EOF
|
||||
{
|
||||
"env": {
|
||||
"OPENROUTER_API_KEY": "${openrouter_key}"
|
||||
},
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"auth": {
|
||||
"token": "${gateway_token}"
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "openrouter/${model_id}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
openclaw_json=$(printf '{\n "env": {\n "OPENROUTER_API_KEY": "%s"\n },\n "gateway": {\n "mode": "local",\n "auth": {\n "token": "%s"\n }\n },\n "agents": {\n "defaults": {\n "model": {\n "primary": "openrouter/%s"\n }\n }\n }\n}\n' "$(json_escape "${openrouter_key}")" "$(json_escape "${gateway_token}")" "$(json_escape "${model_id}")")
|
||||
upload_config_file "${upload_callback}" "${run_callback}" "${openclaw_json}" "~/.openclaw/openclaw.json"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,12 +118,7 @@ print(d.get('password', ''))
|
|||
local config_dir
|
||||
config_dir=$(dirname "${config_file}")
|
||||
mkdir -p "${config_dir}"
|
||||
cat > "${config_file}" << EOF
|
||||
{
|
||||
"username": "${username}",
|
||||
"password": "${password}"
|
||||
}
|
||||
EOF
|
||||
printf '{\n "username": "%s",\n "password": "%s"\n}\n' "$(json_escape "${username}")" "$(json_escape "${password}")" > "${config_file}"
|
||||
chmod 600 "${config_file}"
|
||||
log_info "Credentials saved to ${config_file}"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue