T09 · Insecure Skill Coding Practices
Note
- Location
- scripts/journeys.sh:18
- Finding
- Unencoded datetime permits HTTP query-parameter injection## Vulnerability Details **File Location**: `scripts/journeys.sh`, lines 18–20 **Vulnerability Type**: HTTP query-parameter injection caused by missing URL encoding and input validation **Risk Level**: Low ### Vulnerable Code ```bash if [[ "$mode" == "arrival" ]]; then q="/journeys?from=${from_enc}&to=${to_enc}&arrival=${when}&results=3&stopovers=true" else q="/journeys?from=${from_enc}&to=${to_enc}&departure=${when}&results=3&stopovers=true" fi ``` ### Technical Analysis The script correctly URL-encodes the origin and destination but inserts the caller-controlled `when` argument directly into the query string. Reserved characters such as `&`, `=`, and `#` can therefore change the request structure rather than being treated as part of the datetime value. A legitimate ISO 8601 timestamp containing a `+` timezone offset may also be interpreted incorrectly because form-style query parsers commonly decode `+` as a space. Furthermore, `mode` is not strictly validated: every value other than `arrival` silently selects the `departure` branch. This is HTTP parameter injection, not shell-command injection. The completed URL is passed to `curl` as one quoted argument, and the destination scheme and host remain fixed. ### Attack Path 1. An attacker or untrusted caller invokes the wrapper and controls its fourth argument. 2. The caller supplies a value containing query delimiters, for example: ```text x&results=100 ``` 3. The script directly interpolates that value into the URL: ```text /journeys?...&arrival=x&results=100&results=3&stopovers=true ``` 4. The fixed BVG endpoint receives attacker-injected query parameters. 5. Depending on duplicate-parameter handling by the upstream service, the injected parameter may alter processing, increase the response size, or produce misleading journey data. ### Impact Assessment Exploitation requires control over the script arguments. It can manip ...[truncated 444 chars]
- Remediation
- ## Remediation Suggestions 1. Strictly validate `mode` rather than treating every unexpected value as `departure`: ```bash if [[ "$mode" != "arrival" && "$mode" != "departure" ]]; then printf 'Invalid mode: expected arrival or departure\n' >&2 exit 2 fi ``` 2. Validate `when` as an accepted ISO 8601 datetime or other explicitly supported format before sending it to the API. 3. URL-encode the datetime just as the origin and destination are encoded: ```bash when_enc=$(urlencode "$when") if [[ "$mode" == "arrival" ]]; then q="/journeys?from=${from_enc}&to=${to_enc}&arrival=${when_enc}&results=3&stopovers=true" else q="/journeys?from=${from_enc}&to=${to_enc}&departure=${when_enc}&results=3&stopovers=true" fi ``` 4. Prefer delegating query construction to `curl` so that every value is independently encoded: ```bash curl --silent --get "${base}/journeys" \ --data-urlencode "from=${from_raw}" \ --data-urlencode "to=${to_raw}" \ --data-urlencode "${mode}=${when}" \ --data-urlencode "results=3" \ --data-urlencode "stopovers=true" ``` 5. Add tests covering timezone offsets and reserved characters, including `+`, `&`, `=`, `#`, and percent-encoded input.
