T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/sentinel-output.sh:297
- Finding
- Detected sensitive content is persisted in plaintext audit logs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sentinel-input.sh:463-476`; `scripts/sentinel-output.sh:297-301` **Vulnerability Type**: Plaintext storage of sensitive data **Risk Level**: High ### Vulnerable Code `scripts/sentinel-input.sh:463-476`: ```bash if [[ $THREAT_COUNT -gt 0 ]]; then mkdir -p "$(dirname "$SENTINEL_LOG")" SNIPPET=$(echo "$INPUT" | head -c 200 | tr '\n' ' ') LOG_ENTRY=$(cat <<EOF {"timestamp":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","direction":"input","severity":"$SEVERITY","categories":"$CAT_STRING","threat_count":$THREAT_COUNT,"snippet":"$(echo "$SNIPPET" | sed 's/"/\\"/g')","action":"$(if [[ "$CLEAN_MODE" == true ]]; then echo "sanitized"; else echo "blocked"; fi)"} EOF ) echo "$LOG_ENTRY" >> "$SENTINEL_LOG" 2>/dev/null || true fi ``` `scripts/sentinel-output.sh:297-301`: ```bash if [[ $THREAT_COUNT -gt 0 ]]; then mkdir -p "$(dirname "$SENTINEL_LOG")" SNIPPET=$(echo "$INPUT" | head -c 200 | tr '\n' ' ') LOG_ENTRY="{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"direction\":\"output\",\"severity\":\"$SEVERITY\",\"categories\":\"$CAT_STRING\",\"threat_count\":$THREAT_COUNT,\"snippet\":\"$(echo "$SNIPPET" | sed 's/"/\\"/g')\"}" echo "$LOG_ENTRY" >> "$SENTINEL_LOG" 2>/dev/null || true fi ``` ### Technical Analysis The input and output scanners are specifically intended to detect credentials, private keys, tokens, database connection strings, and other confidential content. When a threat is found, both scanners copy the first 200 characters of the original content into `~/.sentinel/threats.jsonl` by default. Consequently, if sensitive material appears within the first 200 characters, the scanner creates a second plaintext copy of the material it was intended to protect. The code creates the log directory and file without setting an explicit restrictive `umask` or applying `0700` and `0600` permissions. Actual exposure depends on the invoking process's existing `umask`, directory permissions, backup poli ...[truncated 1640 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not store raw input or output snippets for security detections. Log only: - Timestamp. - Direction. - Severity. - Detection category. - Rule identifier. - Content length. 2. If event correlation is necessary, use a keyed HMAC over the content rather than a reversible or plain hash. 3. Set restrictive permissions before creating any Sentinel files: ```bash umask 077 mkdir -p -m 700 "$(dirname "$SENTINEL_LOG")" touch "$SENTINEL_LOG" chmod 600 "$SENTINEL_LOG" ``` 4. Validate that a custom `SENTINEL_LOG` path is owned by the expected user and is not a symbolic link before writing. 5. Implement log retention and secure deletion policies. 6. Use a real JSON serializer, such as `jq -n --arg`, if arbitrary text ever needs to be represented in a log. 7. Add automated tests confirming that representative API keys, JWTs, private keys, and database URIs never appear in the log. ]]>
