T09 · Insecure Skill Coding Practices
- Location
scripts/security_audit.py:947- Finding
Plaintext shell credentials are embedded in persistent audit reports
- Content
View full analysis
Vulnerability Details
File Location:
scripts/security_audit.py:947-960,scripts/security_audit.py:1134-1141, andscripts/security_audit.py:1189-1195
Vulnerability Type: Sensitive information exposure through report generation
Risk Level: HighVulnerable Code
python with open(rc_file, 'r', encoding='utf-8', errors='ignore') as f: content = f.read() matches = export_secret_pattern.findall(content) if matches: sanitized = [m[:50] + "..." if len(m) > 50 else m for m in matches[:3]] results.append(AuditResult( category="密钥与凭据安全", name=f"Shell 配置明文密钥: {rc_file.name}", status="fail", severity="high", description=f"发现 {len(matches)} 处明文导出密钥: {'; '.join(sanitized)}", impact=str(rc_file), fix="将密钥移至 .env 文件或密钥管理服务,不在 shell 配置中硬编码", ))The result description is subsequently inserted into the report:
python if result.status != "pass": report.append(f"- 问题描述: {result.description}") report.append(f"- 影响范围: `{result.impact}`") report.append(f"- 修复建议: `{result.fix}`")The report is then persisted:
python if output_file is None: timestamp = datetime.datetime.now().strftime('%Y%m%d-%H%M%S') output_file = OPENCLAW_DIR / "logs" / f"security-audit-{timestamp}.{extension}" output_path = Path(output_file) output_path.parent.mkdir(parents=True, exist_ok=True) with open(output_path, 'w', encoding='utf-8') as f: f.write(report)Technical Analysis
The scanner intentionally searches shell startup files for exported credentials. However, it treats truncation to 50 characters as sanitization. Many API keys, passwords, tokens, and complete shell assignments are shorter than 50 characters, so the generated report can contain the entire credential. Longer credentials may still expose a useful prefix or substantial secret material.
The resulting report is writte ...[truncated 1453 chars]
- Remediation
View remediation
Remediation Suggestions
- Never place matched credential values or complete export statements in an
AuditResult. - Extract and report only the environment variable name, source file, line number, and detected secret category.
- Replace the current truncation with complete redaction, for example
SERVICE_TOKEN=[REDACTED]. - Ensure JSON reports receive the same redaction treatment.
- Create report files atomically with mode
0600, rather than relying on the process umask. - Set the report directory to mode
0700. - Add tests using short and long credentials to verify that no part of a secret value appears in Markdown, JSON, console output, or generated Feishu messages.
- Advise users to remove and securely destroy reports generated by affected versions and rotate credentials if such reports were shared.
- Never place matched credential values or complete export statements in an
