T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/main.py:153
- Finding
- Detected secrets may be disclosed through terminal and CI output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 153–160 and 267–275 **Vulnerability Type**: Insufficient masking of sensitive information before output **Risk Level**: High ### Vulnerable Code ```python for i, line in enumerate(lines, 1): for pattern, secret_type in self.PATTERNS: if re.search(pattern, line, re.IGNORECASE): # Mask the secret masked = re.sub(r'["\'][^"\']{10,}["\']', '"***MASKED***"', line.strip()) findings.append({ 'line': i, 'type': secret_type, 'content': masked, 'severity': 'critical' }) ``` ```python for filepath in dirpath.rglob('*'): if filepath.is_file() and filepath.stat().st_size < 1024 * 1024: # Skip large files scanned += 1 secrets = detector.scan_file(filepath) if secrets: total_secrets += len(secrets) print(f"\n🔴 {filepath}") for secret in secrets: print(f" Line {secret['line']}: {secret['type']}") print(f" {secret['content']}") ``` ### Technical Analysis The secret detector stores and prints the source line containing each detected credential. Before doing so, it attempts to sanitize the line with a separate regular expression that only masks values enclosed in matching single or double quotation marks and containing at least ten characters: ```python re.sub(r'["\'][^"\']{10,}["\']', '"***MASKED***"', line.strip()) ``` This masking expression is not tied to the regular expression that detected the secret. Several supported secret formats can be present without quotation marks, including AWS access key IDs, GitHub personal access tokens, API keys, and credential-bearing database URLs. Such values match the detection patterns but do not match the masking pattern, so the original credential remains in `secret['content']` and is printed verbatim. Even when a value is quoted, ...[truncated 2068 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not print the source line containing a detected secret. By default, report only: - Relative file path - Line number - Secret type - Remediation guidance 2. If a preview is operationally necessary, redact the exact span matched by the detection expression rather than applying an unrelated masking expression to the entire line: ```python match = re.search(pattern, line, re.IGNORECASE) if match: masked_line = ( line[:match.start()] + "***REDACTED***" + line[match.end():] ) ``` 3. Prefer omitting previews entirely because surrounding text may contain additional credentials or sensitive information not covered by the detector's patterns. 4. Ensure CI systems do not retain historical output produced by vulnerable versions. Restrict access to existing logs and remove affected artifacts where supported. 5. Treat credentials previously printed by this implementation as potentially compromised. Rotate or revoke them and review the relevant service audit logs for unauthorized use. 6. Add regression tests covering quoted and unquoted AWS keys, GitHub tokens, API keys, database URLs, lines containing multiple credentials, and credentials embedded in assignment or configuration syntax. Tests should assert that the original secret never appears in output. ]]>
