T09 · Insecure Skill Coding Practices
- Location
scripts/generate_brief.py:15- Finding
Hard-Coded Tavily API Credential
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This news-briefing skill mostly matches its stated purpose, but it ships a real-looking Tavily API key in source code and has documentation/runtime mismatches that require review before installation.
Review before installing. Do not use the bundled Tavily key; it should be revoked and replaced with a user-supplied secret from an environment variable or secret store. Install dependencies in an isolated environment with pinned versions, and treat the optional Feishu cron setup as an explicit recurring external publish action.
scripts/generate_brief.py:15Hard-Coded Tavily API Credential
SKILL.md:146Unpinned Third-Party Dependency Installation
The documented behavior does not match the effective behavior: the skill performs external network access via Tavily, persists history under ~/.openclaw/creator-intel/history.json, and appears to provide narrower and differently formatted output than claimed. This is dangerous because hidden persistence and undeclared outbound requests undermine informed consent, make data-flow review difficult, and can enable silent collection, retention, or transmission beyond user expectations.
The script hard-codes a live Tavily API key directly in source and uses it for outbound requests. Embedded credentials are easily leaked through source control, logs, package distribution, or prompt exposure, allowing unauthorized third parties to consume the account, incur cost, and access associated service capabilities.
The hard-coded credential is not only stored insecurely but also automatically transmitted in network requests, with no user disclosure or consent boundary. In the context of a news aggregation skill, this expands risk because anyone with code access can silently reuse the token and the skill will contact a third-party service on execution.
The skill indicates capabilities consistent with file read/write and network access, but it does not declare an explicit tool scope or permissions boundary. This is dangerous because users and reviewers cannot easily understand or constrain what the skill may access, increasing the risk of overbroad data access or unintended external communication.
The trigger phrases are broad and lack activation boundaries, so the skill may be invoked in contexts where the user did not intend external search, local history updates, or content generation from this workflow. In a skill with network access and persistence, ambiguous triggering increases the chance of unintended data processing and unexpected side effects.
The markdown instructs users to configure automatic scheduled pushing to an external channel without clearly warning that data will be transmitted off-host on a recurring basis. This is dangerous because users may enable recurring exfiltration-like behavior without understanding the frequency, destination, content scope, or privacy implications of those outbound messages.
The module-level natural-language description is entirely prescriptive in Chinese and frames the skill's behavior around a fixed language/locale. There is no indication that the user can choose another language or that the Chinese-only behavior is required for a region-specific purpose.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def tavily_search(query, max_results=3):
"""Tavily API 搜索技术向内容"""
try:
url = "https://api.tavily.com/search"
headers = {"Content-Type": "application/json"}
payload = {
"api_key": TAVILY_API_KEY,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
]
}
resp = requests.post(url, json=payload, headers=headers, timeout=30)
data = resp.json()
results = []
The manifest specifies an output format of '技术实体 + 动作 + 性能参数' for each item, but the implementation prints only the rewritten title and summary without including the URL in the output line. This is a direct mismatch between the claimed skill behavior and the actual generated brief format.
No suspicious patterns detected.