T09 · Insecure Skill Coding Practices
Error
- Location
- src/llm_client.py:84
- Finding
- Unredacted Security Logs Are Transmitted to a Configurable External API<![CDATA[ ## Vulnerability Details **File Location**: `src/analyzer.py:123-130`, `src/llm_client.py:19-30`, `src/llm_client.py:84-97`, `DESIGN.md:101-104` **Vulnerability Type**: Sensitive information disclosure through an external service **Risk Level**: High ### Vulnerable Code `src/analyzer.py:123-130`: ```python if not os.path.exists(log_file): print(f"❌ File does not exist: {log_file}") sys.exit(1) with open(log_file, "r", encoding="utf-8") as f: log_content = f.read() report = analyze_security_log(log_content, mode) print(report) ``` `src/llm_client.py:19-30`: ```python self.api_key = os.getenv("SILICONFLOW_API_KEY") self.base_url = os.getenv( "SILICONFLOW_BASE_URL", "https://api.siliconflow.cn/v1" ) self.model = os.getenv("SILICONFLOW_MODEL", "Qwen/Qwen3-8B") self.rate_limit = int(os.getenv("API_RATE_LIMIT", "2")) if not self.api_key: raise ValueError("SILICONFLOW_API_KEY is not configured") self.client = OpenAI( api_key=self.api_key, base_url=self.base_url ) ``` `src/llm_client.py:84-97`: ```python # Select the prompt if mode == "detailed": user_prompt = DETAILED_ANALYSIS_PROMPT.format(log_content=log_content) max_tokens = 3000 else: user_prompt = BRIEF_ANALYSIS_PROMPT.format(log_content=log_content) max_tokens = 1500 messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_prompt} ] return self.chat(messages, max_tokens) ``` The design document states that sensitive information is automatically redacted, but no redaction implementation exists in the supplied source code. ### Technical Analysis The application reads the selected log file in full, performs only length-based truncation, embeds the retained content directly into an LLM prompt, and sends it to an OpenAI-compatible remote API. Security logs can contain credentials, authorization headers, session identifiers, access tokens, email addresses, usernames, internal IP addresses, private URLs ...[truncated 2445 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Implement local redaction before any prompt is constructed: - Detect and mask authorization headers, API keys, passwords, cookies, session IDs, private keys, and common token formats. - Support configurable rules for organization-specific identifiers. - Redact sensitive URL query parameters and request bodies. - Preserve only the minimum information needed for analysis. 2. Require explicit user consent before external transmission: - Display the selected provider and destination hostname. - Explain that retained log content will leave the local system. - Provide a preview of the redacted payload. 3. Validate the API destination: - Require HTTPS. - Reject URLs containing unexpected credentials, ports, or schemes. - Use an allowlist of approved provider hostnames where operationally possible. - Require a separate explicit unsafe-mode setting for custom endpoints. 4. Separate credentials by provider and avoid forwarding a production provider key to arbitrary custom endpoints. 5. Add automated tests containing representative secrets and verify that none appear in outbound prompts. 6. Update the documentation so its privacy claims accurately reflect implemented behavior. Do not claim automatic redaction until the feature is implemented and tested. 7. Consider an offline or locally hosted analysis option for highly sensitive incident data. ]]>
