T09 · Insecure Skill Coding Practices
- Location
SKILL.md:92- Finding
Potential Shell Command Injection in Mandatory JSONL Persistence
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 92-97 and 371-374
Vulnerability Type: Shell command injection through unsafe serialization of user-controlled data
Risk Level: HighVulnerable Code
The skill mandates appending JSONL records through Bash:
markdown - **追加 JSONL → 必须用 Bash + `printf` + `>>`**,禁止用 Read+Write 模拟追加(并发/换行/转义易出错): ```bash printf '%s\n' '{"id":"INV-001",...}' >> "$DATA_DIR/invitations.jsonl"text It later demonstrates embedding conversational content directly in a single-quoted shell argument: ```markdown 6. **用户确认或继续聊别的** → Bash 写入: ```bash printf '%s\n' '{"id":"INV-001","date":"2026-05-06","target":"徒步女生","familiarity":"见过1-2次","method":"线上","content":"周末天气好一起爬山?","response":"模糊","selfScore":null,"keyPoint":"","note":""}' >> "$DATA_DIR/invitations.jsonl"text ### Technical Analysis The record fields include user-controlled values such as the target alias, invitation content, reactions, scene descriptions, and conversation summaries. The skill requires these records to be emitted through a Bash command but does not require: - Shell-safe argument construction - Trusted JSON serialization - Separation of user data from shell source - Validation or rejection of shell metacharacters - Use of standard input or positional parameters to establish a safe data boundary The demonstrated command places JSON inside a single-quoted shell string. If an implementation directly substitutes a user-controlled field into that template, an apostrophe can terminate the shell string. Subsequent characters may then be parsed as shell operators or commands. Escaping a value for JSON is insufficient because JSON encoding and shell encoding are different contexts. A value can be valid JSON data while still altering shell parsing when embedded in generated command text. ### Attack Path 1. An attacker supplies a record field, such as invitation content, containing an apostrophe followed by shell syntax. ...[truncated 1312 chars]- Remediation
View remediation
Remediation Suggestions
-
Do not construct shell source from record values. Use a direct append-capable file API wherever possible.
-
Serialize JSON using a trusted encoder. Build the record as a structured object and serialize it with a standard JSON library rather than manually assembling JSON text.
-
Keep serialized data outside the command string. If Bash is unavoidable, pass the already serialized record through standard input, an environment-independent file descriptor, or a safely bounded positional argument. The shell program itself must remain constant.
-
Do not rely on JSON escaping for shell safety. Shell argument handling and JSON encoding must be performed as separate operations appropriate to their respective contexts.
-
Add an explicit prohibition to the skill instructions. State that user-controlled values must never be interpolated into Bash command text, including within quoted JSON literals.
-
Validate before persistence. Enforce the documented types, enumerations, score ranges, date formats, and maximum field lengths before writing a record.
-
Add adversarial tests. Test fields containing apostrophes, quotation marks, backslashes, newlines, command substitutions, redirection operators, semicolons, and non-ASCII characters. Verify that each value is stored literally and that no additional command can execute.
-
Apply least privilege. Run the agent in a sandbox with narrowly scoped filesystem permissions so that any persistence-layer failure has limited impact.
-
