T09 · Insecure Skill Coding Practices
- Location
flight-search.md:37- Finding
Shell Command Injection Through Unquoted Dynamic Arguments
- Content
View full analysis
Vulnerability Details
File Locations:
flight-search.md, lines 37–42hotel-search.md, lines 16–21concert-search.md, lines 78–78 and 96–96diff-tracking.md, lines 67–67 and 83–83
Vulnerability Type: Shell command injection
Risk Level: HighVulnerable Code
flight-search.md, lines 37–42:bash flyai search-flight \ --origin {出发城市} \ --destination {目的地城市} \ --dep-date {去程日期 YYYY-MM-DD} \ --back-date {回程日期 YYYY-MM-DD} \ --sort-type 3hotel-search.md, lines 16–21:bash flyai search-hotel \ --dest-name {目的地城市} \ --key-words {场馆名称或地标} \ --check-in-date {入住日期 YYYY-MM-DD} \ --check-out-date {退房日期 YYYY-MM-DD} \ --sort price_ascconcert-search.md, lines 78 and 96:bash agent-browser open {URL}bash agent-browser --session {name} open {URL}diff-tracking.md, lines 67 and 83:bash ls -t ~/.qoderwork/skills/multi-concert-trip-planner/snapshots/{艺人列表快照ID前缀}*.json | head -1bash ln -sf {快照ID}.json ~/.qoderwork/skills/multi-concert-trip-planner/snapshots/latest.jsonTechnical Analysis
The documented command templates interpolate dynamic values directly into shell command lines without quoting, validation, or structured argument handling.
Several values can originate directly or indirectly from untrusted sources:
- Departure cities and user-supplied artist names originate from user input.
- Destination cities, venue names, and URLs can originate from search results or fetched web content.
- Browser session names and snapshot identifiers are derived from artist names or other dynamic data.
- Dates, prices, and preference values may also be supplied by users or extracted from external content.
If the agent executes these templates through a shell, metacharacters such as semicolons, pipes, command substitutions, redirections, or newlines can terminate or alter the int ...[truncated 2489 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not construct shell command strings. Invoke
flyaiandagent-browserthrough an API that accepts a program name and an argument array, with shell processing disabled.Conceptual safe form:
text execute( program = "flyai", arguments = [ "search-flight", "--origin", validatedOrigin, "--destination", validatedDestination, "--dep-date", validatedDepartureDate, "--back-date", validatedReturnDate, "--sort-type", "3" ], shell = false ) -
Apply strict validation to every dynamic argument.
- Require dates to match
YYYY-MM-DDand verify that they are valid calendar dates. - Parse budget and price limits as bounded numeric values.
- Restrict sort modes, hotel types, star ratings, bed types, and journey types to fixed enumerations.
- Reject control characters, newlines, null bytes, and shell metacharacters in city, venue, artist, and session fields.
- Normalize Unicode before validation to prevent bypasses using visually similar characters.
- Require dates to match
-
Validate browser URLs before use.
- Parse URLs with a dedicated URL parser.
- Permit only
httpsURLs. - Reject embedded credentials, control characters, malformed ports, and non-web schemes.
- Prefer an explicit allowlist of trusted official concert and ticketing domains.
- Treat all fetched page content as untrusted data rather than executable instructions.
-
Replace shell-based snapshot discovery with filesystem APIs.
- Enumerate the snapshot directory programmatically.
- Parse each JSON file and compare its normalized
artistsfield rather than relying on filename globs. - Select the latest matching file using validated metadata or filesystem timestamps.
- Do not execute
ls,head, or other shell pipelines for lookup.
-
Generate snapshot identifiers internally.
- Deri ...[truncated 1339 chars]
-
