T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/scan_draft_gates.py:54
- Finding
- Credential Values Are Copied into Machine-Gate Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan_draft_gates.py`, lines 54–59 and 92–95 **Vulnerability Type**: Sensitive information exposure through diagnostic output **Risk Level**: High ### Vulnerable Code ```python def line_hits(text: str, name: str, pattern: re.Pattern[str], severity: str) -> list[dict]: hits = [] for line_no, line in enumerate(text.splitlines(), 1): if pattern.search(line): hits.append({"severity": severity, "category": name, "line": line_no, "excerpt": line.strip()[:180]}) return hits ``` The function is used directly for credential detection: ```python for name, pattern in SECRET_PATTERNS.items(): issues.extend(line_hits(draft, name, pattern, "P0")) issues.extend(line_hits(draft, "uuid", UUID_PATTERN, "P0")) issues.extend(line_hits(draft, "personal_path", PERSONAL_PATH_PATTERN, "P0")) ``` ### Technical Analysis The scanner correctly identifies several credential formats, including Notion tokens, GitHub tokens, OpenAI-style keys, and private-key headers. However, when a match is found, `line_hits()` copies up to 180 characters from the entire source line into the issue record. The issue records are subsequently serialized to the configured output file, normally `05-machine-gate.json`. Consequently, a credential discovered in the draft is not merely reported—it is duplicated into another artifact. Surrounding confidential text on the same line may also be copied. This violates secure diagnostic-output practices. Security scanners should report the type and location of a secret without reproducing its plaintext value. The project workflow also packages the machine-gate report with other deliverables, increasing the number of people and systems that may receive the exposed value. ### Attack Path 1. A draft contains a valid token, private credential, or confidential value matching one of the scanner patterns. 2. The required `scan_draft_gates.py` workflow is executed. 3. `line ...[truncated 1092 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Never include an unredacted matching line in a secret-detection result. 2. Report only the secret category, line number, and a generic message such as `credential pattern detected`. 3. If correlation is necessary, store a non-reversible keyed digest or a carefully masked value rather than plaintext. 4. Redact the exact match before retaining any surrounding context. For example: ```python def line_hits( text: str, name: str, pattern: re.Pattern[str], severity: str, sensitive: bool = False, ) -> list[dict]: hits = [] for line_no, line in enumerate(text.splitlines(), 1): if pattern.search(line): excerpt = ( pattern.sub("[REDACTED]", line).strip()[:180] if sensitive else line.strip()[:180] ) hits.append({ "severity": severity, "category": name, "line": line_no, "excerpt": excerpt, }) return hits ``` 5. Invoke the function with `sensitive=True` for credentials, UUIDs, and personal paths. 6. Restrict permissions on generated reports and avoid including failed security reports in externally shared packages. 7. Add automated tests using synthetic tokens and verify that no portion of the original token appears in standard output or the JSON report. 8. Rotate any real credential that has already been processed by the vulnerable scanner and remove affected reports from retained artifacts. ]]>
