Back to skill

Security audit

Clawfeed

Security checks for vulnerabilities and agentic risk

Overview

ClawFeed is a coherent news-digest web app, but it needs Review because the artifacts show stored-XSS risk and unsafe test/admin credential handling.

Review before installing on any shared or public service. Fix the unsafe HTML rendering, remove query-string API keys, randomize or isolate test sessions, remove public-host test defaults, rotate the documented staging key if it was real, and update vulnerable dev dependencies. For local-only use, keep the service bound to localhost and do not run test scripts against live data.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
web/index.html:743
Finding

Stored Cross-Site Scripting Through Unsanitized Digest and Source Content

Content
View full analysis
${title}
${excerpt ? `
${excerpt}
` : ''}
${badge}`; ... list.innerHTML = html; ``` Full digest content is also rendered directly as HTML: ```js async function loadDigest(id) { const list = document.getElementById('list'); const viewer = document.getElementById('viewer'); list.innerHTML = ''; try { const resp = await fetch(`${API}/digests/${id}`); const d = await resp.json(); let text = d.content; // Hide private sections for non-logged-in users if (!currentUser) { text = text.replace(/🧹\s*建议取关[\s\S]*?(?=\n(?:💤|🔍|👀|📰|🔖|🔥|—|$))/g, ''); text = text.replace(/🔖\s*Bookmarks\s*精选[\s\S]*?(?=\n(?:💤|🔍|👀|📰|🧹|🔥|—|$))/g, ''); } await loadMarkedUrls(); text = text.replace(/(https?:\/\/x\.com\/[^\s<)]+)/g, (match) => { const clean = match.split('?')[0]; const isMarked = markedUrls.has(clean); const markId = markedUrls.get(clean); let markHtml; if (currentUser) { markHtml = isMarked ? `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
test/setup.sh:6
Finding

Predictable Test Sessions Can Become Authentication Backdoors in Shared or Production Environments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/server.mjs:791
Finding

Administrative API Key Accepted in URL Query Parameters

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (85)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 66)May include surrounding context.

bash
# 1. Copy and edit environment config
cp .env.example .env
# Edit .env with your settings

# 2. Start the API server

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation explicitly claims the tool runs in 'read-only mode with zero credentials,' yet elsewhere documents unauthenticated POST /api/digests and PUT /api/config endpoints. This contradiction can mislead operators into deploying the service with weaker controls than warranted, increasing the chance of unauthorized content creation or configuration changes.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
Serve `web/index.html` via your reverse proxy or any static file server.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · docs/TESTING.md (reported line 164)May include surrounding context.

md
| 13.1 | POST /digests 无 API key | 401 |
| 13.2 | POST /sources 未登录 | 401 |
| 13.3 | POST /packs/install 未登录 | 401 |
| 13.4 | DELETE /sources 未登录 | 401 |
| 13.5 | GET /marks 未登录 | 401 |

### 14. 边界情况 (2+ cases)

Known Vulnerable Dependency: brace-expansion==1.1.12 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
95% confidence
Finding

brace-expansion 1.1.12 is associated with multiple DoS-class issues involving pathological brace patterns that can trigger excessive CPU or memory consumption. Here it is pulled in transitively through minimatch in the eslint/dev toolchain, so the vulnerability is real, though primarily reachable when attacker-controlled glob-like input is processed during development or CI.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: flatted==3.3.3 — 2 advisory(ies): CVE-2026-32141 (flatted vulnerable to unbounded recursion DoS in parse() revive phase); CVE-2026-33228 (Prototype Pollution via parse() in NodeJS flatted)

High
Category
Supply Chain
Confidence
80% confidence
Finding

flatted 3.3.3 has advisories for unbounded recursion DoS and prototype pollution during parse(), and this lockfile includes it transitively via flat-cache in eslint. That makes it a genuine vulnerable dependency, but in this skill the exposure is limited to development-time tooling unless untrusted serialized input is fed into the cache/parsing path.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
93% confidence
Finding

js-yaml 4.1.1 is flagged for several CPU-exhaustion issues from crafted YAML structures, and it appears here as a transitive devDependency under eslint configuration handling. This is a real vulnerability, but in context it is less dangerous because it is not part of the runtime dependency set unless the development tooling parses attacker-supplied YAML configs.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==3.1.3 — 1 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu)

High
Category
Supply Chain
Confidence
92% confidence
Finding

minimatch 3.1.3 is vulnerable to ReDoS from crafted nested extglob patterns that can induce catastrophic backtracking. In this file it is used only in the eslint/dev dependency chain, so the issue is real but mainly affects development or CI workflows that evaluate attacker-controlled glob patterns.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · CONTRIBUTING.md (reported line 9)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 67)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/db.mjs (reported line 9)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/server.mjs (reported line 15)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/db.mjs (reported line 10)May include surrounding context.

js
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {
  for (const line of readFileSync(envPath, 'utf8').split('\n')) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/server.mjs (reported line 16)May include surrounding context.

js
const ROOT = join(__dirname, '..');

// Load .env
const envPath = join(ROOT, '.env');
const env = {};
if (existsSync(envPath)) {
  for (const line of readFileSync(envPath, 'utf8').split('\n')) {

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 106)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 107)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 174)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 188)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 198)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 220)May include surrounding context.

md
### 4. Source Ownership (3 tests)
| # | Case | Method |
|---|------|--------|
| 4.1 | Bob cannot delete Alice's source → 403 | `DELETE /sources/:id` |
| 4.2 | Alice deletes her private source | `DELETE /sources/:id` |
| 4.3 | Alice's subscription count decreases | `GET /subscriptions` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · test/README.md (reported line 140)May include surrounding context.

md
### 9. Subscription Management (2 tests)
| # | Case | Method |
|---|------|--------|
| 9.1 | Carol unsubscribes → count decreases | `DELETE /subscriptions/:sourceId` |
| 9.2 | Carol re-subscribes → count restores | `POST /subscriptions` |

### 10. Marks — CRUD + Isolation (7 tests)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · test/e2e.sh (reported line 274)May include surrounding context.

sh
# Visitor blocked
  check_code "Visitor cannot access marks → 401" "401" \
    "$(curl -s -o /dev/null -w '%{http_code}' "$API/marks")"

  # Alice deletes her mark
  if [ -n "$A_MARK" ] && [ "$A_MARK" != "None" ]; then

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · test/e2e.sh (reported line 301)May include surrounding context.

sh
# Alice's private source is gone (deleted earlier), but let's verify subscriptions don't leak
ALICE_SUBS=$(curl -s "$API/subscriptions" -H "$ALICE" | python3 -c "import sys,json; print(','.join(str(s['id']) for s in json.load(sys.stdin)))" 2>/dev/null)
BOB_SUBS=$(curl -s "$API/subscriptions" -H "$BOB" | python3 -c "import sys,json; print(','.join(str(s['id']) for s in json.load(sys.stdin)))" 2>/dev/null)
CAROL_SUBS=$(curl -s "$API/subscriptions" -H "$CAROL" | python3 -c "import sys,json; print(','.join(str(s['id']) for s in json.load(sys.stdin)))" 2>/dev/null)
echo "     Alice subs: [$ALICE_SUBS]"
echo "     Bob subs:   [$BOB_SUBS]"