Back to skill

Security audit

Cctv News Fetcher Litiao

Security checks for vulnerabilities and agentic risk

Overview

The skill has a clear news-fetching purpose, but its crawler can follow unvalidated links from remote pages and send a hardcoded cookie to unintended destinations.

Review this skill before installing in environments with access to private networks or sensitive internal services. It should restrict article fetches to known CCTV hosts, validate redirects, remove the hardcoded cookie unless strictly required, and pin dependency installation to the lockfile.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/news_crawler.js:98
Finding

Unvalidated Remote URLs Permit Arbitrary Outbound Requests

Content
View full analysis
a.getAttribute('href') || ''); 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 }); ``` Equivalent unvalidated URL extraction and fetching occurs in all three crawler implementations: ```js const pageUrls = rawList.slice(1).map(item => item.match(/(http.*)/)?.[0].split('\'')[0] || ''); ``` ```js const pageUrls = soup.querySelectorAll('#contentELMT1368521805488378 li a') .slice(1) .map(a => a.getAttribute('href') || ''); ``` ### Technical Analysis The crawler initially contacts a fixed CCTV URL, but subsequently treats links extracted from the returned HTML as trusted request destinations. It does not validate: - The destination hostname - The URL scheme or port - Redirect destinations - Whether DNS resolution produces a loopback, private, link-local, or metadata-service address - Whether the destination remains within the expected CCTV domain Remote HTML is an external trust boundary. If the source page is compromised, modified in transit at an upstream system, or contai ...[truncated 1809 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/news_crawler.js:105
Finding

Hardcoded Tracking Cookie Is Disclosed to Unvalidated Destinations

Content
View full analysis
{ try { const pageResponse = await fetch(pageUrl, { headers }); ``` The same fixed cookie value appears in each of the three crawler functions at lines 17, 62, and 105. ### Technical Analysis The code embeds a persistent cookie identifier directly in the source and manually attaches it to article requests. Because `pageUrl` is derived from remote HTML and is not restricted to an approved host, the header may be transmitted to unintended destinations. The identified value appears to be a tracking-style identifier rather than an authenticated user credential. The audit found no collection or transmission of local files, environment variables, user credentials, or private Agent context. Consequently, this finding represents unnecessary identifier disclosure and tracking risk, not demonstrated compromise of a privileged account. A cookie is not required for ordinary retrieval of public news unless the service explicitly enforces it. Sending a persistent identifier therefore exceeds the minimum information needed for the declared functionality. ### A ...[truncated 966 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to execute a local JavaScript crawler that performs network access, but the manifest does not declare any explicit tool scope such as allowed-tools or permissions. This creates an authorization gap where a user-invocable skill can trigger code with broader capabilities than are transparently declared, increasing the risk of unintended external requests or abuse through the crawler path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The only provided invocation example is written in Chinese, which can indicate the skill is intended to operate in a specific language without documenting any user language choice. Under the policy, language constraints should be opt-in or clearly justified.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency version is specified with a caret range (^7.0.2), which allows newer minor and patch releases to be installed automatically. This can introduce supply-chain risk because future upstream releases may contain vulnerable or malicious code, and builds may become non-reproducible across environments. In this skill's context, the package is a network-fetching/parser utility, so compromise of a parsing dependency could affect any environment running the skill, though the package.json alone does not indicate active exploitation.

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.0.2"
    }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request headers explicitly set Accept-Language to zh-CN,zh;q=0.9,en;q=0.8, which hard-codes a language/locale preference. This is a natural-language policy concern because the file provides no user choice, opt-in, or documented region-specific justification for forcing that locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This function also sets Accept-Language to zh-CN,zh;q=0.9,en;q=0.8, enforcing a locale choice in natural-language-related request metadata. Because no opt-in or justification is present, it matches the policy-violation category for forced language/locale behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The third crawler path again forces Accept-Language to prefer Chinese, with no mechanism for the user to select another language or acknowledge the constraint. This is a consistent language-policy issue across the file rather than an isolated implementation detail.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.