T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/privacy-scan.sh:92
- Finding
- Unredacted Sensitive Values Are Printed to Scan Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/privacy-scan.sh`, lines 92–98 and representative output at lines 118–119 **Vulnerability Type**: Sensitive information exposure through diagnostic output **Risk Level**: Medium ### Vulnerable Code ```bash results=$(grep -rn --include="*.sh" --include="*.md" --include="*.json" --include="*.yaml" --include="*.yml" --include="*.ts" --include="*.js" --include="*.plist" \ "$pattern" "$SCAN_DIR" 2>/dev/null | head -5 || true) echo "$results" ``` A representative caller subsequently prints the complete matching lines: ```bash if [ -n "$results" ]; then fail "发现疑似真实 Webhook URL:" echo "$results" | while IFS= read -r line; do echo " $line"; done else pass "无真实 Webhook URL" fi ``` The same output pattern is used across checks for API keys, bearer tokens, passwords, JWTs, database connection strings, webhooks, and private-key content. ### Technical Analysis The scanner invokes `grep -rn`, which returns the file path, line number, and complete text of every matching line. Those results are emitted verbatim to standard output. Because the patterns are specifically designed to locate secrets, the displayed line can contain the complete secret rather than merely identifying its location. Output may consequently be retained in CI logs, terminal recordings, Agent transcripts, build artifacts, or centralized log aggregation systems. This expands access to a secret beyond the users and processes that could read the original file. A privacy scanner only needs to identify the affected file, line number, and secret type. Printing the underlying value is unnecessary for the declared functionality. ### Attack Path 1. A scanned repository contains a real API token, password, webhook URL, JWT, database credential, or other supported secret. 2. A user or automated pipeline runs `privacy-scan.sh` against that repository. 3. `grep -rn` captures the complete line containing the secret. 4. The scrip ...[truncated 1207 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not print complete matching lines. Report only the file path, line number, and finding category. 2. Prefer output such as: ```text path/to/file:42: [REDACTED API KEY] ``` 3. Use file-only reporting when line-level detail is unnecessary: ```bash grep -rl --include="*.sh" --include="*.md" ... "$pattern" "$SCAN_DIR" ``` 4. If line numbers are required, parse the `grep -n` result and replace the content after the location fields with a fixed redaction marker. 5. Do not attempt generic redaction by printing part of a secret. Even prefixes, suffixes, or surrounding connection-string components may expose sensitive metadata. 6. Add regression tests containing synthetic secrets and assert that none of the secret values appear in standard output or standard error. 7. Document that scan output is security-sensitive and should not be uploaded or retained until all output paths have been made safe. ]]>
