Back to skill

Security audit

Claw Cctv News Fetcher

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but its crawler can follow unvalidated links from CCTV pages to other network locations, so it should be reviewed before installation.

Install only if you are comfortable running a local news crawler with outbound network access. Prefer using it in a sandboxed environment, and consider requiring CCTV-domain URL allowlisting, request timeouts, response-size limits, bounded concurrency, and removal of unnecessary hardcoded headers before routine use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/news_crawler.js:9
Finding

Unrestricted Fetching of Server-Supplied URLs Enables SSRF

Content
View full analysis
item.match(/(http.*)/)?.[0].split('\'')[0] || ''); const headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Cache-Control': 'no-cache', 'Cookie': 'cna=DLYSGBDthG4CAbRVCNxSxGT6', 'Host': 'tv.cctv.com', 'Pragma': 'no-cache', 'Proxy-Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' }; const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); const pageText = await pageResponse.text(); ``` The other crawler paths use the same unsafe pattern: ```javascript const pageUrls = soup.querySelectorAll('#contentELMT1368521805488378 li a') .slice(1) .map(a => a.getAttribute('href') || ''); const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); ``` ```javascript const pageUrls = soup.querySelectorAll('li a').slice(1).map(a => a.getAttribute('href') || ''); const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); ``` ### Technical Analysis The initial index requests use fixed CCTV URLs, but article URLs are subsequently extracted from remotely supplied HTML and fetched without validating their scheme, host ...[truncated 2247 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/news_crawler.js:24
Finding

Unbounded Concurrent Requests and Response Buffering Permit Resource Exhaustion

Content
View full analysis
{ try { const pageResponse = await fetch(pageUrl, { headers }); const pageText = await pageResponse.text(); const soup = parse(pageText); ``` This pattern is repeated in the older, mid-range, and recent news crawler functions. ### Technical Analysis The crawler imposes no explicit limits on: - Request duration - Number of extracted article links - Concurrent outbound requests - Redirect count beyond runtime defaults - Response body size - Accepted response content type - HTML parser input size `Promise.all(pageUrls.map(...))` starts a request for every extracted URL concurrently. Each response is then fully buffered in memory through `response.text()` before parsing. If a remote index contains an unusually large number of links, or if linked endpoints return very large or indefinitely slow responses, the crawler can consume excessive sockets, memory, CPU time, and execution time. This is an availability flaw rather than evidence of intentional malicious behavior. ### Attack Path 1. An attacker gains the ability to influence a news index page or one of its linked article endpoints. 2. The manipulated index supplies a large number of article links, or links to endpoints that respond slowly or return oversized bodies. 3. The crawler launches all article requests concurrently through `Promise.all`. 4. Slow requests remain active because no application-level timeout is configured. 5. Large bodies are completely buffered by `response.text()` and passed to the HTML parser. 6. The Skill process experiences excessive memo ...[truncated 552 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs the agent to execute a local JavaScript crawler that performs network activity, but the manifest declares no explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where code with network capability may run without clear least-privilege constraints, making review, enforcement, and sandboxing weaker.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction says to calculate dates like "yesterday" or "today" relative to the current local time, which imposes a locale/timezone choice implicitly. For a user-facing skill, this can produce incorrect results for users in other time zones and constitutes a language/locale policy issue because no user choice or explicit justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown example uses a Chinese-only prompt as the sole illustrated invocation, which imposes a specific language/locale expectation without offering user choice. Under the policy, language constraints should be optional or explicitly justified when they are region-specific.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a caret range (^7.1.0), which allows newer minor and patch releases to be installed over time. This can introduce supply-chain risk and reduce build reproducibility if an upstream package is compromised or a breaking change slips into an allowed version.

Content

Scanner excerpt · package.json (reported line 7)May include surrounding context.

json
"description": "Fetch news from CCTV",
    "main": "scripts/news_crawler.js",
    "dependencies": {
        "node-html-parser": "^7.1.0"
    }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request headers explicitly force Accept-Language to prefer zh-CN, which is a natural-language locale choice embedded in the code. The file does not offer any user choice or documented justification for this enforced locale, so it fits the language/locale policy-violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This header set again forces Accept-Language to zh-CN,zh;q=0.9,en;q=0.8, imposing a specific language/locale preference. Because no opt-in or justification is present, this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The crawler's third request path also sets Accept-Language to prioritize Chinese regardless of user preference. That constitutes a locale policy issue because the code enforces a language setting without giving the user a choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.