Back to skill

Security audit

Chill Beijing

Security checks for vulnerabilities and agentic risk

Overview

This skill runs live browser scraping and then presents mostly hard-coded Beijing recommendations as current data, with unsafe browser settings.

Review carefully before installing. Run it only in an isolated environment without sensitive files or credentials, and do not rely on its event times, prices, availability, or venue claims unless you verify them directly with the listed platforms or venues.

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

Error
Location
scripts/data-fetcher.mjs:72
Finding

Chromium Sandbox Disabled While Processing Untrusted External Content

Content
View full analysis

Vulnerability Details

File Location: scripts/data-fetcher.mjs:72-75, scripts/data-fetcher.mjs:124-127, scripts/data-fetcher.mjs:176-179, and scripts/data-fetcher.mjs:212-215
Vulnerability Type: Browser sandbox bypass through unsafe Puppeteer configuration
Risk Level: High

Vulnerable Code

javascript
browser = await puppeteer.launch({
  headless: 'new',
  args: ['--no-sandbox', '--disable-setuid-sandbox']
});

The same unsafe launch configuration is used by the Maoyan, Damai, Meituan, and Xiaohongshu scraping functions.

Technical Analysis

The Puppeteer configuration explicitly disables Chromium's operating-system process sandbox and setuid sandbox. These security boundaries normally isolate browser renderer processes from the host account and filesystem.

Each browser subsequently navigates to externally controlled websites and processes their pages, scripts, advertisements, and third-party resources. If any loaded content exploits a vulnerability in the bundled Chromium version, disabling the sandbox can allow the exploit to escape the renderer directly into the Node.js process's host security context.

This configuration is especially risky in an agent environment because the Node.js process may have access to project files, user files, environment variables, browser data, API credentials, or other agent resources.

Attack Path

  1. An attacker compromises one of the target websites, a third-party script, advertising resource, or another resource loaded by the page.
  2. The Skill launches Chromium with both sandbox mechanisms disabled.
  3. Puppeteer navigates to the compromised content.
  4. The hostile page exploits a compatible Chromium renderer vulnerability.
  5. Because Chromium is running without its process sandbox, the payload executes with the permissions of the Node.js process.
  6. The payload may access files, environment variables, credentials, and network resources ava ...[truncated 1003 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove --no-sandbox and --disable-setuid-sandbox, allowing Chromium to use its normal process isolation:

    javascript
    browser = await puppeteer.launch({
      headless: 'new'
    });
    
  2. Configure the deployment host so Chromium's sandbox is supported rather than disabling it to work around environment limitations.

  3. If sandboxed Chromium cannot be supported, run scraping inside a dedicated unprivileged container or virtual machine with:

    • A non-root user.
    • A read-only root filesystem.
    • No mounted credentials or sensitive host directories.
    • A minimal writable temporary directory.
    • Restricted outbound networking limited to required domains.
    • Dropped Linux capabilities and a restrictive seccomp/AppArmor profile.
  4. Keep Puppeteer and its bundled Chromium version patched and regularly monitor browser security advisories.

  5. Reuse one hardened browser instance where practical instead of repeatedly creating independently configured unsafe instances.

  6. Block unnecessary third-party requests, downloads, pop-ups, and navigation to domains outside an explicit allowlist.

other

Warning
Location
scripts/generate-recommendations.mjs:53
Finding

Hard-Coded Recommendations Are Misrepresented as Current Fetched Data

Content
View full analysis

Vulnerability Details

File Location: scripts/generate-recommendations.mjs:53-446, with invocation at scripts/generate-recommendations.mjs:461-483
Vulnerability Type: Misleading output and data-integrity failure
Risk Level: Medium

Vulnerable Code

The formatter accepts fetched data but does not use it. Instead, it returns hard-coded recommendations containing specific ratings, schedules, prices, venues, and travel details:

javascript
function formatWorkdayRecommendations(data) {
  let output = '';
  
  // Movies - 6 items
  output += '\n🎬 **Tonight\'s Movie Recommendations (6 films)**\n\n';
  
  output += '**Popular Theatrical Releases**\n\n';
  output += '1. **Project Hail Mary** ⭐8.5 | Science Fiction/Adventure | Starring Ryan Gosling\n';
  output += '   📍 Wanda Cinema CBD, Broadway Cinematheque apm, Lumiere Cinema | ⏰ 19:00/19:30/20:00 showings | 💰 CNY 45-85 | Runtime: 134 minutes\n';

The fetched object is passed to the formatter, but the formatter ignores its contents:

javascript
const data = await fetchWorkdayData();
output += '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
output += '🌅 **Places to Go After Work Tonight**\n';
output += formatWorkdayRecommendations(data);

The weekend formatter follows the same design. Furthermore, the purported Meituan and Xiaohongshu integrations unconditionally return empty arrays after navigation:

javascript
console.log('[Meituan] Fetch completed (selectors must be adjusted for the actual page)');
return [];
javascript
console.log(`[Xiaohongshu] Search completed: ${keyword} (must be adjusted for the actual page)`);
return [];

Technical Analysis

The Skill documentation promises real-time, current-day recommendations from external sources. However, the recommendation formatters do not read any property from their data parameters. Network requests therefore have no effect on the displayed f ...[truncated 2226 chars]

Remediation
View remediation

Remediation Suggestions

  1. Construct every displayed recommendation exclusively from successfully fetched and validated records.
  2. Remove static schedules, prices, ratings, and event claims unless they are explicitly labeled as examples or non-current editorial suggestions.
  3. Validate each record before display:
    • Confirm that its date is current or future.
    • Confirm venue and event identity.
    • Parse prices and availability from the source.
    • Include the source URL and retrieval timestamp.
  4. If a source fails or returns no records, omit that category or clearly state that current data is unavailable.
  5. Do not list a platform as a source unless at least one displayed recommendation was derived from it.
  6. Add automated tests that provide distinct fixture data and verify that formatter output changes accordingly.
  7. Implement the currently stubbed Meituan and Xiaohongshu extraction logic before claiming those sources are supported.
  8. Reconcile the documentation with actual behavior, including unsupported JSON output, nonexistent exports, the missing formatter file, and conflicting package versions.
  9. Preserve provenance in the internal data model, for example with source, sourceUrl, retrievedAt, eventDate, and verifiedAt fields.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
Findings (12)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/data-fetcher.mjs` - 数据抓取模块(猫眼/大麦/美团/小红书)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises and invokes code that performs live network scraping, but the manifest does not declare any explicit tool scope or allowed network capability. This weakens consent and policy enforcement because users and the host runtime are not clearly informed that external requests and browser automation will occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description emphasizes real-time scraping from multiple third-party platforms but gives no warning that the skill will transmit requests to external services and may process live third-party content. Users may unknowingly trigger outbound network activity, exposing usage metadata and creating consent and privacy issues.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation explicitly states that Puppeteer is used to simulate a real browser for anti-bot scraping, yet there is no warning about browser automation, external page execution, or potential impact on third-party services. This increases risk because automated browsing can execute untrusted web content and perform site-interacting behavior without informed user consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file hardcodes 'zh-CN' in date formatting and presents all generated recommendation text in Chinese, which imposes a specific language/locale on users. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script claims to provide real-time scraped recommendations, but the generated output is almost entirely hardcoded and ignores the fetched category data. This creates a deceptive integrity issue: users may rely on outdated, fabricated, or nonexistent listings, prices, venues, and schedules while believing they are current.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The package description uses Chinese text only, which can amount to a language/locale constraint without any stated opt-in or justification. Under the policy criteria, forcing a specific language is a potential natural-language policy violation unless the skill offers language choice or clearly documents a region-specific constraint.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using a caret range for puppeteer allows installation of newer releases within the major version, which can reduce build reproducibility and unintentionally pull in a compromised or breaking dependency. While not evidence of active malicious behavior, dependency drift increases supply-chain risk, especially for a package like Puppeteer that drives a browser and processes untrusted web content.

Content

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

json
"weekend": "node scripts/generate-recommendations.mjs --weekend"
  },
  "dependencies": {
    "puppeteer": "^22.0.0"
  },
  "keywords": [
    "beijing",

Unverifiable Dependency: puppeteer has 1 known advisory(ies) (CVE-2019-5786 (Use-After-Free in puppeteer)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The date formatting is hard-coded to use the 'zh-CN' locale, which is a natural-language/locale constraint. The file does not provide an opt-in, fallback, or justification that this skill is intentionally limited to a China-specific locale.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The file header comment states '每个类别至少3项活动', implying each category will contain at least three items. However, some categories in the generated output explicitly contain only 3 items while others vary, and the implementation is entirely static rather than enforcing this rule from data, so the comment describes a guaranteed behavior that the code does not actually validate or maintain. This is an intent/documentation divergence because the comment reads like an invariant, but the code has no mechanism to ensure it remains true.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code formats the generation time with toLocaleString('zh-CN'), reinforcing a fixed locale choice for user-visible output. This is a natural-language/locale policy concern because users are not offered any alternative locale or opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.