T09 · Insecure Skill Coding Practices
- Location
secret_scanner.py:524- Finding
Unmasked Secrets Exposed in JSON Reports
- Content
View full analysis
Vulnerability Details
File Location:
secret_scanner.py, lines 524–531 and 625
Vulnerability Type: Plaintext sensitive-data exposure
Risk Level: HighVulnerable Code
python line_preview = line.strip()[:120] finding = SecretFinding( pattern_name=pattern_def["name"], severity=pattern_def["severity"], file_path=rel_path, line_number=i, line_preview=line_preview, secret_preview=masked, description=pattern_def["description"], remediation=pattern_def["remediation"] )python 'findings': [asdict(f) for f in report.findings],Technical Analysis
The scanner masks the regex match before assigning it to
secret_preview, but separately stores the first 120 characters of the original source line inline_preview. No redaction is applied to that field.The JSON formatter serializes the entire
SecretFindingdataclass throughasdict(f), including the unredactedline_preview. Consequently, a detected credential located within the first 120 characters of its source line is reproduced in plaintext in JSON output.This violates the documented claim that secret masking makes reports safe to share. The Markdown formatter currently does not display
line_preview, but the sensitive value remains stored in the report object and is disclosed by JSON serialization.Attack Path
-
A scanned file contains a hardcoded credential within the first 120 characters of a line.
-
A user or CI pipeline executes:
bash python secret_scanner.py /path/to/project --json -
A configured regular expression detects the credential.
-
The scanner masks the matched text for
secret_preview. -
The scanner also copies the original source line into
line_previewwithout redaction. -
format_json()serializes every finding field usingasdict(f). -
The complete credential is exposed in terminal output, CI logs, report artifacts, tickets, or other systems receiving the JSON report.
No special p ...[truncated 980 chars]
-
- Remediation
View remediation
Remediation Suggestions
- Redact every matched span before retaining a line preview. Construct the preview from the source line with all secret-pattern matches replaced by a fixed marker such as
[REDACTED]. - Prefer not to store raw source lines in
SecretFinding. Retain only the file path, line number, pattern name, and a safely masked match. - Explicitly select safe JSON fields instead of serializing the complete dataclass with
asdict(). - Ensure masking handles multiple credentials on the same line and overlapping pattern matches.
- Avoid partial masking that leaves enough material to reconstruct or misuse credentials.
- Add regression tests asserting that the original matched value never appears in:
- JSON output
- Markdown output
- Standard output
- Reports written through
--output
- Review downstream logs and previously generated reports for exposed credentials. Rotate any credential that may already have been disclosed.
- Update documentation only after all output paths have been verified to redact sensitive values consistently.
- Redact every matched span before retaining a line preview. Construct the preview from the source line with all secret-pattern matches replaced by a fixed marker such as
