T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/yotta_secret.py:401
- Finding
- Default Scan Reports Can Disclose Plaintext Secrets Through Snippet Fields<![CDATA[ ## Vulnerability Details **File Location**: `scripts/yotta_secret.py`, lines 401–403, 430–433, and 532–543 **Vulnerability Type**: Sensitive information exposure caused by incomplete output redaction **Risk Level**: High ### Vulnerable Code Normal file and standard-input scanning: ```python display = value if opts.show_secret else mask_secret(value) snippet = line.strip() snippet = snippet[: span[0]] + display + snippet[span[1]:] findings.append({ "rule_id": rule.id, "rule_name": rule.name, "category": rule.category, "severity": rule.severity, "file": fname, "line": lineno, "secret": display, "length": len(value), "entropy": round(shannon_entropy(value), 3), "snippet": snippet[:200], "commit": "", "path_in_commit": "", }) ``` Private-key scanning: ```python display = "[PRIVATE KEY REDACTED]" if opts.show_secret: display = value[:12] + "...(%d chars)" % len(value) snippet = " ".join(value.split())[:200] findings.append({ "rule_id": rule.id, "rule_name": rule.name, "category": rule.category, "severity": rule.severity, "file": fname, "line": lineno, "secret": display, "length": len(value), "entropy": round(shannon_entropy(value), 3), "snippet": snippet, "commit": "", "path_in_commit": "", }) ``` Git-history scanning: ```python display = value if opts.show_secret else mask_secret(value) findings.append({ "rule_id": rule.id, "rule_name": rule.name, "category": rule.category, "severity": rule.severity, "file": cur_path, "line": 0, "secret": display, "length": len(value), "entropy": round(shannon_entropy(value), 3), "snippet": content.strip()[:200], "commit": commit, "path_in_commit": cur_path, }) ``` ### Technical Analysis The scanner claims to mask secrets unless `--show-secret` is explicitly supplied. Although the `secret` field is masked by default, the associated `snippet` field is not consistently ...[truncated 2268 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Redact every output field derived from source content, not only the `secret` field. 2. Apply match offsets before stripping or otherwise transforming the source line: ```python snippet = line[:span[0]] + display + line[span[1]:] snippet = snippet.strip()[:200] ``` 3. Prefer applying a centralized redaction function to the final snippet: ```python snippet = redact_text(line).strip()[:200] ``` 4. For private-key findings, never include content from the key block in default snippets. Use a fixed value such as: ```python snippet = "[PRIVATE KEY REDACTED]" ``` 5. In git-history mode, replace the matched span with `display`, or pass the complete line through `redact_text()` before adding it to a finding. 6. Ensure that redaction handles multiple secrets on the same line rather than replacing only the current match. 7. Add regression tests that serialize complete text, JSON, and CSV reports and assert that the original secret does not appear anywhere when `--show-secret` is absent. 8. Add dedicated tests for: - indented credential assignments; - private-key blocks; - git-history findings; - multiple secrets on one line; - secrets near the 200-character truncation boundary. ]]>
