T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:10- Finding
Unescaped JSONL Serialization and Spreadsheet Formula Injection in CSV Exports
- Content
View full analysis
> "$DATA_DIR/data.jsonl" } ``` ```bash cmd_export() { local fmt="${1:-json}" local out="pid-export.$fmt" if [ ! -f "$DATA_DIR/data.jsonl" ]; then echo "No data."; return 0; fi case "$fmt" in json) cp "$DATA_DIR/data.jsonl" "$out" ;; csv) echo "timestamp,command,value" > "$out" while IFS= read -r line; do ts=$(echo "$line" | grep -o '"ts":"[^"]*' | cut -d'"' -f4) c2=$(echo "$line" | grep -o '"cmd":"[^"]*' | cut -d'"' -f4) vl=$(echo "$line" | grep -o '"val":"[^"]*' | cut -d'"' -f4) echo "$ts,$c2,$vl" >> "$out" done < "$DATA_DIR/data.jsonl" ;; *) echo "Formats: json, csv"; return 1 ;; esac echo "Exported: $out ($(wc -c < "$out") bytes)" } ``` ### Technical Analysis The `_save_entry` function embeds the user-controlled `val` argument directly into a JSON string. It does not escape quotation marks, backslashes, carriage returns, newlines, or other JSON control characters. An entry containing these characters can therefore terminate the intended string, create additional properties, or inject additional JSONL records. The export implementation does not use a JSON parser. Instead, it extracts fields with `grep` and `cut`, so malformed or specially constructed records can produce truncated, misleading, or incorrectly parsed output. The CSV exporter also writes fields without RFC 4180 quoting or escaping. Commas, quotation marks, and newlines can create additional columns or rows. In addition, a value b ...[truncated 1955 chars]- Remediation
View remediation
> "$DATA_DIR/data.jsonl" ``` 2. Parse stored records with `jq` or another standards-compliant JSON parser instead of `grep` and `cut`. 3. Generate CSV using a library or helper that implements RFC 4180: - Enclose every field in double quotes. - Replace each embedded double quote with two double quotes. - Preserve newlines only inside properly quoted fields. 4. Neutralize spreadsheet formulas where exports may be opened interactively. Prefix fields beginning with `=`, `+`, `-`, or `@` with an apostrophe, or provide a clearly documented safe-export mode that treats every value as text. 5. Add tests covering quotation marks, backslashes, commas, newlines, Unicode text, and formula-leading characters. 6. Consider validating existing JSONL records during reads and rejecting malformed records with a clear error instead of silently parsing partial values. ]]>
