T09 · Insecure Skill Coding Practices
- Location
scripts/tavily_search.py:11- Finding
Hard-Coded Tavily API Credential Used as an Automatic Fallback
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent fact-checking tool, but it embeds and stores Tavily API credentials in unsafe ways and sends verification text to external search services without enough user-facing disclosure.
Review before installing. Do not use the bundled Tavily fallback key, and do not paste a Tavily API key unless you are comfortable with it being written to ~/.rumor-buster-config as plaintext. Avoid verifying private messages, internal business content, or personal data unless you accept that the text may be sent to third-party search services.
scripts/tavily_search.py:11Hard-Coded Tavily API Credential Used as an Automatic Fallback
sub-skills/setup/setup.py:240Tavily API Keys Are Persisted in Plaintext Without Enforced File Permissions
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
try:
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
The skill claims constrained fact-checking behavior, but the documented implementation also introduces undeclared external API usage, local configuration handling, and behavior that does not clearly match the promised verification workflow. This mismatch is dangerous because users and reviewers may authorize the skill under false assumptions, while sensitive claims or local environment details are sent externally or processed in ways not disclosed.
The documented schema stores a Tavily API key in plaintext under ~/.rumor-buster-config, which exposes the credential to other local processes, backups, logs, or accidental disclosure. Plaintext secret storage is especially risky because compromise of the key can enable unauthorized API use, billing abuse, and access to associated account resources.
The schema includes a plaintext API key and provides no warning about credential handling, which can lead users to paste secrets into an insecure storage path without understanding the risk. Lack of disclosure compounds the underlying secret-storage weakness by making unsafe handling more likely and harder for users to detect.
The skill documents capabilities that imply filesystem access, local config writes, subprocess/subagent spawning, and outbound network use, but it declares no explicit tool scope or permissions boundary. That makes the skill harder to sandbox and review, and can lead to unintended access to local files, shell, or network resources if the host agent grants broad defaults.
Broad trigger phrases like 'Is this true?' or 'Check this' can cause unintended activation on ordinary conversation, leading the skill to process content the user did not intend to send to verification tools. In this skill's context, accidental invocation can expose private text to search providers or spawn setup/reconfiguration flows unexpectedly.
The skill describes searching user-provided claims across multiple engines, optional Tavily API use, and writing a local config file, but it does not clearly warn users that their inputs may be transmitted to third-party services and stored locally. This creates a privacy and consent risk, especially when users submit sensitive rumors, personal messages, or confidential claims for verification.
The architecture adds a setup sub-skill that creates and manages a persistent local configuration file, including search-engine configuration and potentially credentials, which expands the skill's privileges beyond transient fact-checking. For a news-verification skill, persistent local state and delegated setup logic increase the attack surface and create unnecessary opportunities for credential exposure or unauthorized file writes.
The design describes generating a local config file and tracking quota usage without clearly warning the user that data will be written to disk. Silent persistence undermines user expectations, may store operational metadata unexpectedly, and increases privacy and security risk if the filesystem is shared, backed up, or inspected later.
This section says that once language is auto-detected, all subsequent output uses that language until a new verification starts. That is a natural-language policy concern because it imposes a language choice without explicit user opt-in or an offered override.
This markdown file defines separate 'Chinese Template' and 'English Template' sections, but nowhere specifies that the user's preferred language should be selected or that locale choice is optional. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.
The detailed-report structure explicitly separates 'Chinese Search' and 'English Search' / '中文搜索' and '英文搜索' as required workflow elements, implying a fixed bilingual process regardless of user preference. Because no opt-in or justification is provided, this can violate the language/locale policy described in SQP-3.
This code contains natural-language instructions stating the tool performs 'deep English search' and requires 'English search keywords'. That is a language-policy constraint presented as mandatory behavior, with no user choice or opt-in for other languages.
A hardcoded fallback API key is embedded directly in the script, which exposes a secret to anyone with code access and encourages accidental use of a shared credential. If the repository is published or the skill is redistributed, the key can be abused for unauthorized API usage, billing fraud, or quota exhaustion.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
include_answer: 是否包含 AI 生成的答案总结
max_results: 返回结果数量 (1-10)
"""
url = "https://api.tavily.com/search"
payload = {
"api_key": TAVILY_API_KEY,
The script transmits user-provided queries to a third-party service without any explicit user-facing notice or consent mechanism. In a fact-checking skill, users may paste sensitive rumors, personal messages, or internal content, so silent forwarding to an external provider creates a meaningful data exposure risk.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
try:
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
The skill description presents setup as simple detection and configuration generation, but omits that it may read credentials from the environment and perform outbound checks to third-party services. This weak disclosure undermines informed consent and makes the other behaviors more dangerous, because users and reviewers cannot accurately assess the trust boundary from the metadata alone.
The manual trigger phrases include very generic terms like 'setup', '设置', and 'reset', which can easily appear in ordinary conversation. Overly broad activation increases the chance the setup routine runs unintentionally, causing config changes, environment credential access, or external network checks without clear user intent. Because this skill can delete existing config and probe services, accidental triggering has meaningful consequences.
The setup logic reads TAVILY_API_KEY directly from the environment and then uses it for a live external request. Even though it is limited to a named variable rather than arbitrary enumeration, it still accesses sensitive credentials implicitly and transmits them during setup without an upfront, clear consent boundary in the skill contract. In a setup skill, that broadens data access beyond passive capability detection and creates unnecessary secret-handling risk.
The docstring and nearly all prompts and status messages are in Chinese, and the script does not provide any user opt-in or alternative locale. This can violate a language/locale policy when a skill forces a specific language without offering choice or documenting that it is intentionally region-specific.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 尝试导入或调用 kimi_search
# 这里通过检查命令是否存在来判断
import subprocess
result = subprocess.run(
["which", "kimi_search"],
capture_output=True,
text=True,
The setup flow collects and reuses a Tavily API key, and later persists it in a local config file. Storing third-party API credentials expands the skill's access beyond simple fact-checking and creates a credential exposure risk if the file is readable by other local users, backed up insecurely, or later exfiltrated by other software.
The Tavily API key is written to a plaintext local config file without any visible warning that credentials will be stored on disk. Plaintext secret storage increases the chance of compromise through local user access, permissive file permissions, endpoint backups, or accidental disclosure during support/debugging.
The setup script writes a configuration file under the user's home directory, including engine metadata and potentially sensitive settings, which is a side effect not evident from the skill's high-level fact-checking description. Undocumented local state changes are risky because users may not expect file creation or persistence, and those files may later expose secrets or be tampered with.
No suspicious patterns detected.