T09 · Insecure Skill Coding Practices
- Location
run.sh:22- Finding
Unsafe Authentication Header Construction Causes Curl Argument Injection and Credential Exposure
- Content
View full analysis
Vulnerability Details
File Location:
run.sh, lines 22–34
Vulnerability Type: Unquoted command substitution and unsafe curl argument construction
Risk Level: MediumVulnerable Code
bash auth_header() { if [ -n "$API_KEY" ]; then echo "-H" "Authorization: Bearer $API_KEY" fi } api_call() { local method="$1" endpoint="$2" body="$3" curl -s -X "$method" \ "$LOCAL_URL$endpoint" \ -H "Content-Type: application/json" \ $(auth_header) \ -d "$body" }Technical Analysis
The output of
auth_headeris inserted into the curl command through the unquoted command substitution$(auth_header). Bash consequently performs word splitting and pathname expansion on that output.For example, a normal API key causes the intended argument:
text Authorization: Bearer API_KEYto be split into multiple command-line arguments resembling:
text -H Authorization: Bearer API_KEYCurl treats
Authorization:as the value of-H, whileBearerand the API key can be interpreted as additional URLs rather than as parts of the header. Authentication therefore becomes malformed even when the API key is benign.If an attacker can influence
FIRECRAWL_API_KEY, whitespace-delimited curl options or parameters embedded in the value may additionally modify curl's behavior. Shell metacharacters in the value are not reparsed as shell syntax, so this is not direct arbitrary shell-command execution; however, curl argument injection remains possible through word splitting.Attack Path
FIRECRAWL_API_KEYis configured with a normal secret or a value influenced by an attacker.- A user or agent invokes the skill to scrape, map, or crawl a URL.
auth_headerprints the header option and API key as plain text.- The unquoted
$(auth_header)expression undergoes shell word splitting and pathname expansion. - Curl receives the API ...[truncated 1240 chars]
- Remediation
View remediation
Remediation Suggestions
Construct curl arguments using a Bash array so each option and value remains exactly one argument:
bash api_call() { local method="$1" endpoint="$2" body="$3" local -a args args=( -s -X "$method" -H "Content-Type: application/json" -d "$body" ) if [[ -n "$API_KEY" ]]; then args+=(-H "Authorization: Bearer $API_KEY") fi curl "${args[@]}" -- "$LOCAL_URL$endpoint" }Additional hardening measures should include:
- Remove
auth_header, since emitting command-line arguments as text encourages unsafe reparsing. - Keep every curl argument in an array and expand it with
"${args[@]}". - Place
--before the final URL to prevent URL values beginning with a hyphen from being interpreted as options. - Restrict
FIRECRAWL_LOCAL_URLto expected HTTP or HTTPS schemes and trusted hosts when remote endpoints are not required. - Avoid printing the API key in diagnostics or error output.
- Add tests using keys containing spaces, wildcard characters, leading hyphens, and curl-like option text to verify that each key remains a single header value.
- Remove
