T09 · Insecure Skill Coding Practices
- Location
scripts/curl_examples.sh:45- Finding
Unescaped User-Controlled Video URL Allows JSON Request-Body Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/curl_examples.sh, lines 45-55
Vulnerability Type: JSON injection caused by unsafe string interpolation
Risk Level: MediumVulnerable Code
bash if [[ "${VIDEO_SOURCE}" =~ ^https?:// ]]; then SUBMIT_RESP="$(curl -sS -X POST "${BASE_URL}/video-trans/orchestrate" \ -H "Authorization: Bearer ${API_KEY}" \ -H 'Content-Type: application/json' \ --data-binary @- <<JSON { "video_url": "${VIDEO_SOURCE}", "target_language": "${TARGET_LANGUAGE}" } JSON )"VIDEO_SOURCEoriginates from the script's first command-line argument:bash VIDEO_SOURCE="$1"Technical Analysis
The script constructs a JSON document by directly interpolating the user-controlled
VIDEO_SOURCEvalue into a heredoc. Shell variable expansion does not perform JSON encoding. Characters such as double quotes, backslashes, control characters, and newlines can therefore terminate the original JSON string or introduce additional JSON properties.For example, a source argument with an injected fragment could cause the generated body to resemble:
json { "video_url": "https://example.com/video.mp4", "injected_property": "attacker-controlled", "target_language": "en" }The precise effect depends on the remote API's JSON parser, duplicate-property handling, and support for additional fields. Even when injected properties are rejected, a crafted value can reliably produce malformed JSON and disrupt job submission.
This is not shell command injection because the value is expanded as heredoc content rather than evaluated as shell syntax. The confirmed weakness is manipulation of the outbound JSON request body.
Attack Path
- An attacker influences or supplies the video URL passed as the first argument to
curl_examples.sh. - The supplied value begins with
http://orhttps://, satisfying the URL branch condi ...[truncated 1271 chars]
- An attacker influences or supplies the video URL passed as the first argument to
- Remediation
View remediation
Remediation Suggestions
Construct the request with a real JSON serializer rather than interpolating values into JSON text. For example:
bash REQUEST_BODY="$( python3 -c ' import json import sys print(json.dumps({ "video_url": sys.argv[1], "target_language": sys.argv[2], })) ' "${VIDEO_SOURCE}" "${TARGET_LANGUAGE}" )" SUBMIT_RESP="$( curl -sS -X POST "${BASE_URL}/video-trans/orchestrate" \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ --data-binary "${REQUEST_BODY}" )"Additional hardening should include:
- Parse the supplied URL with a URL-aware library and require the scheme to be exactly
httporhttps. - Reject control characters in command-line URL input before submission.
- Validate that the serialized body can be parsed as JSON before sending it.
- Enforce a reasonable maximum URL length.
- Ensure the remote service rejects unknown properties and validates every accepted field against a strict schema.
- Add regression tests using URLs containing quotes, backslashes, Unicode characters, and newlines to verify that they remain a single encoded JSON string.
- Parse the supplied URL with a URL-aware library and require the scheme to be exactly
