Low Risk — Risk Score 25/100
Last scan:2 days ago Rescan
25 /100
rumor-buster
Dual-engine fact-checking skill combining Chinese and English search to verify messages and trace their origins
Legitimate dual-engine fact-checking skill with no malicious behavior, but contains a hardcoded API key in tavily_search.py which is a credential-leak concern.
Skill Namerumor-buster
Duration49.2s
Enginepi
Safe to install
Remove the hardcoded API key fallback in scripts/tavily_search.py line 12. Always require TAVILY_API_KEY from environment. No other security action needed.

Findings 4 items

Severity Finding Location
Medium
Hardcoded API key in tavily_search.py
A fallback API key is hardcoded directly in scripts/tavily_search.py line 12. This is a credential-leak risk: if the key is a real production key, it could be extracted from the skill package. The fallback should be removed so the script fails cleanly when the env var is missing.
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "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")
→ Remove the default value. Change to: os.environ["TAVILY_API_KEY"] with a clear error if not set. Alternatively use a dummy/dev key placeholder that cannot be mistaken for a real credential.
scripts/tavily_search.py:12
Low
Undeclared network requests during setup detection
setup.py performs HTTP GET requests to multiple external domains (sogou.com, wx.sogou.com, so.toutiao.com, duckduckgo.com, startpage.com) to test engine availability. These are not declared in SKILL.md. While functionally appropriate for a search-detection tool, they represent network:READ behavior that should be documented.
req = urllib.request.Request(test_url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=10)
→ Add a network:READ declaration in sub-skills/setup/SKILL.md or add a note that the setup phase performs connectivity checks to search engine domains.
sub-skills/setup/setup.py:84
Low
Undeclared filesystem write
The setup script writes to ~/.rumor-buster-config. This is a filesystem:WRITE operation that is not declared in either the main SKILL.md or the sub-skill SKILL.md.
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
    json.dump(config, f, ensure_ascii=False, indent=2)
→ Document filesystem:WRITE for the setup sub-skill in its SKILL.md.
sub-skills/setup/setup.py:152
Low
Broad tool detection via globals().get()
The setup sub-skill attempts dynamic import of search tools by name using globals().get(). While not malicious, this pattern could accidentally pick up unintended tools if naming collisions occur.
module = globals().get(search)
→ Replace dynamic globals lookup with explicit tool imports or a controlled registry.
sub-skills/setup/SKILL.md:140
ResourceDeclaredInferredStatusEvidence
Filesystem NONE READ ✓ Aligned setup.py reads ~/.rumor-buster-config; setup.py reads skill path ~/.openclaw/wor…
Filesystem NONE WRITE ✓ Aligned setup.py writes ~/.rumor-buster-config via save_config()
Network NONE READ ✓ Aligned tavily_search.py POSTs to api.tavily.com; setup.py tests search engine availabil…
Shell NONE NONE setup.py uses subprocess.run(['which', 'kimi_search']) only within the setup sub…
15 findings
🔗
Medium External URL 外部 URL
https://img.shields.io/badge/version-0.4.0-blue.svg
README.md:3
🔗
Medium External URL 外部 URL
https://img.shields.io/badge/license-MIT-green.svg
README.md:4
🔗
Medium External URL 外部 URL
https://tavily.com
README.md:236
🔗
Medium External URL 外部 URL
https://api.tavily.com/search
scripts/tavily_search.py:23
🔗
Medium External URL 外部 URL
https://sogou.com
sub-skills/setup/SKILL.md:303
🔗
Medium External URL 外部 URL
https://wx.sogou.com
sub-skills/setup/SKILL.md:304
🔗
Medium External URL 外部 URL
https://so.toutiao.com
sub-skills/setup/SKILL.md:305
🔗
Medium External URL 外部 URL
https://duckduckgo.com
sub-skills/setup/SKILL.md:306
🔗
Medium External URL 外部 URL
https://startpage.com
sub-skills/setup/SKILL.md:307
🔗
Medium External URL 外部 URL
https://www.sogou.com/web?query=test
sub-skills/setup/setup.py:84
🔗
Medium External URL 外部 URL
https://wx.sogou.com/weixin?type=2&query=test
sub-skills/setup/setup.py:85
🔗
Medium External URL 外部 URL
https://so.toutiao.com/search?keyword=test
sub-skills/setup/setup.py:86
🔗
Medium External URL 外部 URL
https://duckduckgo.com/html/?q=test
sub-skills/setup/setup.py:107
🔗
Medium External URL 外部 URL
https://www.startpage.com/sp/search?query=test
sub-skills/setup/setup.py:108
🔗
Medium External URL 外部 URL
https://tavily.com/
sub-skills/setup/setup.py:235

File Tree

6 files · 75.4 KB · 2647 lines
Markdown 4f · 2134L Python 2f · 513L
├─ 📁 scripts
│ └─ 🐍 tavily_search.py Python 106L · 3.0 KB
├─ 📁 sub-skills
│ └─ 📁 setup
│ ├─ 🐍 setup.py Python 407L · 13.3 KB
│ └─ 📝 SKILL.md Markdown 531L · 15.8 KB
├─ 📝 README.md Markdown 347L · 10.3 KB
├─ 📝 README.zh.md Markdown 347L · 9.9 KB
└─ 📝 SKILL.md Markdown 909L · 23.1 KB

Dependencies 1 items

PackageVersionSourceKnown VulnsNotes
requests unpinned pip No Used in tavily_search.py; no version constraint specified

Security Positives

✓ No reverse shell, C2, or data exfiltration behavior observed
✓ No access to sensitive paths like ~/.ssh, ~/.aws, or .env credentials
✓ No eval(), base64 decode, or other code injection patterns
✓ No curl|bash or wget|sh remote script execution
✓ Uses standard library requests/urllib for network calls — no shell wrapping
✓ No hidden instructions in HTML comments or documentation
✓ Subprocess usage in setup.py is scoped to 'which' command for tool detection only
✓ Configuration file stored in user home directory, not in shared locations