T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/secret-scanner.sh:79
- Finding
- Secret Scanner Discloses Detected Credentials in JSON Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/secret-scanner.sh`, lines 79-83 **Vulnerability Type**: Sensitive information exposure through diagnostic output **Risk Level**: High ### Vulnerable Code ```bash if [[ "$OUTPUT_FORMAT" == "json" ]]; then local escaped_match escaped_match=$(echo "$match" | sed 's/"/\\"/g' | head -c 120) printf '{"severity":"%s","file":"%s","line":%s,"pattern":"%s","match":"%s"}\n' \ "$severity" "$file" "$line" "$pattern" "$escaped_match" ``` ### Technical Analysis The scanner stores the complete matching source line in the `match` argument and includes up to 120 characters of that value in JSON output. Because the scanner searches for API keys, passwords, authentication tokens, and private-key markers, this output can contain complete live credentials. The human-readable format avoids printing the matching value, but JSON mode explicitly returns it. JSON output is particularly likely to be consumed by CI pipelines, report collectors, agent logs, or security-information systems, expanding the number of locations in which a credential may persist. The manual quote substitution is also not sufficient JSON escaping. Backslashes, newlines, control characters, and other JSON-sensitive content are not safely encoded, potentially creating malformed output or allowing a matched line to inject misleading JSON content. ### Attack Path 1. A repository or workspace contains a live credential matching one of the scanner's regular expressions. 2. A user, agent, or CI pipeline runs: ```bash scripts/secret-scanner.sh --format=json /path/to/repository ``` 3. The matching source line is passed to `emit_finding`. 4. Up to 120 characters of the line, potentially including the complete credential, are printed under the `match` property. 5. The output is retained in CI logs, agent conversation history, audit artifacts, terminal history, or centralized logging. 6. Anyone able to read those secondary recor ...[truncated 534 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `match` value from all output formats. Report only: - Relative file path - Line number - Secret type - Severity 2. If correlation is necessary, calculate a one-way fingerprint from the matched credential and expose only a short fingerprint, never the credential itself. 3. If masking is required, retain no more than a small non-sensitive suffix, such as the final four characters. 4. Generate JSON with a real JSON serializer rather than manual string interpolation. 5. Prevent audit reports from being written with permissive filesystem modes. Use a restrictive `umask`, such as: ```bash umask 077 ``` 6. Add tests confirming that known sample tokens never appear in human-readable output, JSON output, combined reports, or error messages. 7. Document that old audit logs generated by the vulnerable version should be searched, securely deleted where appropriate, and treated as potentially containing exposed credentials. ]]>
