T09 · Insecure Skill Coding Practices
- Location
scripts/tavily_search.py:285- Finding
Verbose Mode Logs the Tavily API Key in Plaintext
- Content
View full analysis
Vulnerability Details
File Location:
scripts/tavily_search.py, lines 285-298
Vulnerability Type: Sensitive credential exposure through diagnostic logging
Risk Level: HighVulnerable Code
python payload = { "api_key": key, "query": query, "max_results": min(max_results, 10), "search_depth": search_depth, "include_answer": bool(include_answer), "include_images": False, "include_raw_content": False, } if verbose: print(f"发送请求到Tavily API...", file=sys.stderr) print(f"查询: {query}", file=sys.stderr) print(f"参数: {json.dumps(payload, indent=2)}", file=sys.stderr)Technical Analysis
The request payload contains the complete Tavily API key. When the documented
--verboseoption is enabled, the entire payload is serialized and written to standard error without redaction.Standard error is commonly captured by CI systems, agent execution traces, shell-session recorders, container logging drivers, and centralized logging platforms. Consequently, a diagnostic operation can transform a credential that was originally held in an environment variable or protected configuration file into persistent plaintext log data.
Although the key is legitimately required for requests to Tavily, exposing it in diagnostics is unnecessary for the Skill's declared functionality and violates secret-handling best practices.
Attack Path
- A user or automated agent configures a valid
TAVILY_API_KEY. - The user runs the documented command with
--verbose. - The script constructs
payloadwith the complete API key. json.dumps(payload, indent=2)writes that key to standard error.- A local user, CI operator, log aggregation service, or other party with access to captured output retrieves the key.
- The exposed key can be reused to issue Tavily requests under the victim's account.
Impact Assessment
An attacker who obtains the logged key ...[truncated 344 chars]
- A user or automated agent configures a valid
- Remediation
View remediation
Remediation Suggestions
-
Never serialize a secret-bearing payload directly into logs.
-
Create a redacted diagnostic copy before logging:
python if verbose: safe_payload = {**payload, "api_key": "***REDACTED***"} print("Sending request to Tavily API...", file=sys.stderr) print(f"Query: {query}", file=sys.stderr) print(f"Parameters: {json.dumps(safe_payload, indent=2)}", file=sys.stderr) -
Prefer logging only non-sensitive fields instead of copying the payload.
-
Add automated tests that run verbose mode with a sentinel key and assert that the sentinel never appears in stdout or stderr.
-
Review historical logs generated by verbose mode and remove or rotate exposed keys where necessary.
-
