T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/tracer.py:52
- Finding
- Unredacted Operation Metadata and Results Persisted in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tracer.py:52-68`, `scripts/tracer.py:70-89`, and `scripts/tracer.py:91-113` **Vulnerability Type**: Sensitive data exposure through plaintext trace storage **Risk Level**: Medium ### Vulnerable Code ```python def start_span(self, name: str, op_type: str, metadata: dict = None) -> str: """开始追踪一个操作 Args: name: 操作名称 op_type: 操作类型(tool_call / llm_call / error / compression) metadata: 附加元数据 Returns: span_id: 追踪跨度ID """ span_id = str(uuid.uuid4())[:8] span = Span( id=span_id, name=name, start_time=time.time(), metadata=metadata or {}, ) span.metadata["operation_type"] = op_type self._active_spans[span_id] = span return span_id ``` ```python def end_span(self, span_id: str, result: Any = None, status: str = "success"): """结束追踪 Args: span_id: 追踪跨度ID result: 操作结果 status: 状态(success / error) """ if span_id not in self._active_spans: return span = self._active_spans[span_id] span.end_time = time.time() span.duration_ms = (span.end_time - span.start_time) * 1000 span.result = str(result) if result is not None else None span.status = status # 持久化到 SQLite self._save_span(span) # 从活跃列表移除 self._active_spans.pop(span_id, None) ``` ```python def _save_span(self, span: Span): """保存 span 到数据库""" conn = sqlite3.connect(self.db_path) conn.execute( """INSERT OR REPLACE INTO traces (id, timestamp, operation_type, operation_name, duration_ms, metadata, result, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", ( span.id, span.start_time, span.metadata.get("operation_type", "unknown"), span.name, span.duration_ms, json.dumps(span.metadata, ensure_ascii=False), span.result, span.status, ...[truncated 2266 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define an explicit allowlist of safe metadata fields for each operation type instead of persisting arbitrary dictionaries. 2. Recursively redact fields whose names indicate sensitive content, including `password`, `secret`, `token`, `api_key`, `authorization`, `cookie`, and related variants. 3. Avoid storing complete tool or LLM results by default. Store status codes, hashes, sizes, or bounded summaries instead. 4. Apply strict maximum lengths to operation names, metadata values, and results. 5. Make sensitive-content capture an explicit, documented opt-in feature. 6. Create the database and its parent directory with owner-only permissions, such as `0700` for the directory and `0600` for the database where supported. 7. If trace contents must remain recoverable, encrypt sensitive fields using a key held outside the database. 8. Implement and automatically invoke a bounded retention policy rather than relying only on manual calls to `cleanup()`. 9. Apply the same authorization and redaction controls to JSON and CSV exports. 10. Add tests verifying that nested secrets, authorization headers, credentials in URLs, and oversized results are removed or truncated before persistence. ]]>
