T09 · Insecure Skill Coding Practices
- Location
SKILL.md:56- Finding
Audit Log Injection Through Unescaped Event Data
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 56–61 and 89–96
Vulnerability Type: Audit-log injection and malformed JSON generation
Risk Level: MediumVulnerable Code
Lines 56–61:
bash log_audit() { local EVENT_TYPE=$1 local DETAILS=$2 echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $EVENT_TYPE $DETAILS" >> ~/.pilot/audit/events.jsonl }Lines 89–96:
bash audit_log() { local EVENT_TYPE=$1 local AGENT=$2 local ACTION=$3 local RESULT=$4 cat >> "$LOG_FILE" <<EOF {"timestamp":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","event_type":"$EVENT_TYPE","agent":"$AGENT","action":"$ACTION","result":"$RESULT"} EOF }Technical Analysis
Both logging implementations interpolate input directly into audit records without applying JSON encoding or rejecting newline and control characters.
The first implementation writes an unstructured, space-delimited record to a file named
events.jsonl. This conflicts with subsequent examples that process the same file as JSON. A value containing a newline can create additional attacker-controlled log lines.The second implementation places variables directly inside JSON string literals. An agent identifier or other value containing quotation marks, backslashes, newlines, or JSON syntax can terminate the intended field, corrupt the record, or inject additional fields and forged records. Shell variable expansion does not recursively execute shell syntax contained in these values, so the demonstrated issue is log and JSON injection rather than shell command execution.
Attack Path
- An attacker supplies or influences an agent identifier, event detail, action, or result processed by the wrapper.
- The attacker includes quotation marks, JSON delimiters, or newline characters in that value.
- The logging function interpolates the value directly into
events.jsonl. - The crafted value creates malformed JSON or ...[truncated 727 chars]
- Remediation
View remediation
Remediation Suggestions
-
Generate every JSONL record with a JSON-aware encoder instead of string interpolation. For example:
bash jq -cn \ --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ --arg event_type "$EVENT_TYPE" \ --arg agent "$AGENT" \ --arg action "$ACTION" \ --arg result "$RESULT" \ '{timestamp:$timestamp,event_type:$event_type,agent:$agent,action:$action,result:$result}' \ >> "$LOG_FILE" -
Use one consistent JSONL schema throughout initialization, logging, querying, and reporting.
-
Validate identifiers and event types against explicit allowlists where practical.
-
Reject unexpected control characters when multiline values are not required.
-
Quote all filesystem paths and initialize the audit directory with restrictive permissions, such as
umask 077and directory mode0700. -
Validate generated records with
jq -ebefore committing them to the authoritative audit log. -
Consider append-only or integrity-protected storage if the audit trail is intended to provide compliance or forensic evidence.
-
