Back to skill

Security audit

小红书内容灵感专家

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it advertises, but it handles API credentials and generated reports in ways that create avoidable security risk.

Review this skill before installing. It needs a RedFox API key and contacts redfox.hk, which fits its purpose, but you should avoid letting it scan shell startup files for credentials, avoid permanent credential writes unless you intend them, and treat generated HTML reports as active web pages that may load third-party scripts. The API key should be supplied through a scoped secret or environment variable, and the TLS-verification and HTML-escaping issues should be fixed before use with sensitive accounts or data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_explosive_articles.py:241
Finding
API credentials transmitted over connections with TLS certificate verification disabled<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/fetch_explosive_articles.py:241-275` - `scripts/xiaohongshu-similar-account.py:293-319` **Vulnerability Type**: Improper TLS certificate and hostname validation **Risk Level**: High ### Vulnerable Code `scripts/fetch_explosive_articles.py:241-275`: ```python http_request = ( f"GET {full_path} HTTP/1.1\r\n" f"Host: {host}\r\n" f"X-API-KEY: {api_key or ''}\r\n" f"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n" f"Accept: application/json, text/plain, */*\r\n" f"Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" f"Connection: close\r\n" f"\r\n" ) # DNS resolution ip_address = socket.gethostbyname(host) # Create socket connection sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(45) sock.connect((ip_address, 443)) # SSL wrapping context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE ssl_sock = context.wrap_socket(sock, server_hostname=None) ssl_sock.sendall(http_request.encode('utf-8')) ``` `scripts/xiaohongshu-similar-account.py:293-319`: ```python api_key = get_api_key() payload = { "redId": redId if redId else "", "track": track if track else "", "maxFans": maxFans if maxFans else "", "minFans": minFans if minFans is not None else "", "level": level if level else "", "source": "小红书对标账号-ClawHub" } headers = { "Content-Type": "application/json", "X-API-KEY": api_key } data = json.dumps(payload).encode("utf-8") req = urllib.request.Request(url, data=data, headers=headers, method="POST") ssl_ctx = ssl.create_default_context() ssl_ctx.check_hostname = False ssl_ctx.verify_mode = ssl.CERT_NONE try: with urllib.request.urlopen(req, context=ssl_ctx, timeout=30) as resp: result = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis Both implementations deliberately disable certificate-chain verification an ...[truncated 2369 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove both TLS-verification overrides: - Do not set `check_hostname` to `False`. - Do not set `verify_mode` to `ssl.CERT_NONE`. 2. Preserve Server Name Indication and hostname validation: ```python context = ssl.create_default_context() with socket.create_connection(("redfox.hk", 443), timeout=45) as sock: with context.wrap_socket(sock, server_hostname="redfox.hk") as tls_sock: tls_sock.sendall(http_request.encode("utf-8")) ``` 3. For `urllib`, use its verified default context: ```python with urllib.request.urlopen(req, timeout=30) as resp: result = json.loads(resp.read().decode("utf-8")) ``` Alternatively: ```python ssl_ctx = ssl.create_default_context() with urllib.request.urlopen(req, context=ssl_ctx, timeout=30) as resp: result = json.loads(resp.read().decode("utf-8")) ``` 4. Prefer a mature HTTP client rather than manually parsing HTTP over raw sockets. 5. Fail closed on certificate errors. Do not retry with verification disabled. 6. Rotate any API keys previously used over hostile or untrusted networks. 7. Add automated tests confirming that self-signed certificates and hostname mismatches are rejected. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/fetch_explosive_articles.py:97
Finding
Broad shell startup-file scanning exceeds the privileges required to retrieve one API key<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/fetch_explosive_articles.py:97-157` - `scripts/crawl_xhs.py:25-40` - `scripts/fetch_rank.py:24-40` - `scripts/fetch_xhs_hot_articles.py:17-32` - `scripts/gen_xhs_html.py:42-58` - `scripts/xhs_daily_fetcher.py:40-56` - `scripts/xiaohongshu-similar-account.py:255-268` - `SKILL.md:41-47` **Vulnerability Type**: Excessive access to sensitive user configuration files **Risk Level**: Medium ### Vulnerable Code `scripts/fetch_explosive_articles.py:97-157`: ```python def get_redfox_api_key() -> str: api_key = os.getenv("REDFOX_API_KEY", "").strip() if api_key: print( f"[鉴权] 从环境变量读取到 REDFOX_API_KEY(前8位: {api_key[:8]}...)", file=sys.stderr ) return api_key home = os.path.expanduser("~") shell_configs = [] if sys.platform == "win32": ps_profile = os.path.join( home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1" ) shell_configs.append(ps_profile) ps7_profile = os.path.join( home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1" ) shell_configs.append(ps7_profile) shell_configs.append(os.path.join(home, ".bashrc")) shell_configs.append(os.path.join(home, ".bash_profile")) else: shell_configs = [ os.path.join(home, ".zshrc"), os.path.join(home, ".bashrc"), os.path.join(home, ".bash_profile"), os.path.join(home, ".profile"), ] for config_path in shell_configs: if os.path.exists(config_path): try: with open(config_path, 'r', encoding='utf-8') as f: for line in f: line_stripped = line.strip() if line_stripped.startswith('#') or not line_stripped: c ...[truncated 4594 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all automatic scanning of `.zshrc`, `.bashrc`, `.bash_profile`, `.profile`, `.zprofile`, and PowerShell profile files. 2. Read the credential exclusively from the process environment: ```python def get_redfox_api_key() -> str: api_key = os.environ.get("REDFOX_API_KEY", "").strip() if not api_key: raise RuntimeError( "REDFOX_API_KEY is not configured in the process environment." ) return api_key ``` 3. If file-based configuration is necessary, use a dedicated file such as `~/.config/redfox/credentials`: - Require restrictive permissions such as mode `0600`. - Parse only a narrowly defined format. - Do not search unrelated files. 4. Never print the key or any key prefix. Log only whether authentication configuration was found. 5. Do not instruct users to run commands that print the complete secret for verification. Verify only that the variable is non-empty. 6. Update `SKILL.md` and associated references to describe environment-only or dedicated-file configuration. 7. Add tests confirming that the Skill never opens shell startup files. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_explosive_articles.py:756
Finding
Untrusted API data is inserted into generated HTML and JavaScript without context-aware escaping<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/fetch_explosive_articles.py:756-823,904-907` - `scripts/gen_xhs_html.py:297,600-677` - `scripts/xiaohongshu-similar-account.py:840-847,887-953` - `scripts/generate_xhs_report.py:69-76` - `assets/report_template.html:109,137-145` **Vulnerability Type**: Stored HTML and JavaScript injection in generated reports **Risk Level**: High ### Vulnerable Code `scripts/fetch_explosive_articles.py:756-823` directly inserts remote fields into HTML text and attribute contexts: ```python def get_article_html(article: dict, rank: int) -> str: try: title = article.get("title", "无笔记标题") or "无笔记标题" photo_url = article.get("photoJumpUrl", "#") user_name = article.get("userName", "未知作者") user_url = article.get("userJumpUrl", "#") fans = article.get("fans", "0") desc = article.get("desc", "") like_count = article.get("useLikeCount", "0") collect_count = article.get("collectedCount", "0") comment_count = article.get("useCommentCount", "0") share_count = article.get("useShareCount", "0") interactive_count = article.get("interactiveCount", "0") analysis = generate_content_analysis(desc, title) user_head_url = article.get("userHeadUrl", "") if user_head_url: author_html = ( f'<img src="{user_head_url}" class="author-avatar" ' f'alt="{user_name}">{user_name}({fans} 粉丝)' ) else: author_html = ( f'<span class="author-avatar-placeholder"></span>' f'{user_name}({fans} 粉丝)' ) return f''' <div class="article-item"> <div class="article-body"> <div class="article-rank {top_class}">{rank}</div> <div class="article-content"> <a href="{photo_url}" target="_blank" class=" ...[truncated 5745 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply context-aware output encoding: - Use `html.escape(value, quote=True)` for HTML text and quoted attributes. - Do not reuse HTML escaping for JavaScript contexts. 2. Validate every remote URL before placing it in `href` or `src`: - Permit only `https`. - Restrict hosts to expected Xiaohongshu/CDN domains where practical. - Reject control characters, `javascript:`, `data:`, and unexpected schemes. 3. Replace HTML string concatenation and `innerHTML` with DOM-safe operations: ```javascript const titleLink = document.createElement('a'); titleLink.textContent = String(d.title || '--'); titleLink.href = validateUrl(d.photoJumpUrl) || '#'; titleLink.target = '_blank'; titleLink.rel = 'noopener noreferrer'; ``` 4. When embedding JSON in HTML: - Prefer a non-executable `application/json` element. - Escape `<`, `>`, `&`, U+2028, and U+2029. - Read and parse its `textContent`. Example: ```html <script id="report-data" type="application/json">{{SAFE_JSON}}</script> <script> const RAW = JSON.parse( document.getElementById('report-data').textContent ); </script> ``` 5. Escape the JSON server-side before insertion: ```python works_json = json.dumps(works, ensure_ascii=False) works_json = ( works_json .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` 6. Add `rel="noopener noreferrer"` to links opened with `target="_blank"`. 7. Add a restrictive Content Security Policy that disallows inline and unexpected remote scripts. 8. Add regression tests using payloads containing quotes, angle brackets, event handlers, `javascript:` URLs, and closing script tags. ]]>

T08 · Insecure Dependencies

Warning
Location
assets/preview-template.html:8
Finding
Generated reports execute third-party CDN scripts without integrity verification<![CDATA[ ## Vulnerability Details **File Locations**: - `assets/preview-template.html:8-19` - `scripts/gen_xhs_html.py:307-308` - `scripts/generate_rank_report.py:408` **Vulnerability Type**: Unpinned executable browser dependencies and unsafe CDN fallbacks **Risk Level**: Medium ### Vulnerable Code `assets/preview-template.html:8-19`: ```html <script src="https://cdn.jsdelivr.net/npm/html2pdf.js@0.10.1/dist/html2pdf.bundle.min.js"></script> <script> if (typeof html2pdf === 'undefined') { var script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js'; document.head.appendChild(script); } </script> <script> if (typeof html2pdf === 'undefined') { var script = document.createElement('script'); script.src = 'https://unpkg.com/html2pdf.js@0.10.1/dist/html2pdf.bundle.min.js'; document.head.appendChild(script); } </script> ``` `scripts/gen_xhs_html.py:307-308`: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> ``` `scripts/generate_rank_report.py:408`: ```html <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> ``` ### Technical Analysis The generated HTML reports download and execute JavaScript when opened. Although the URLs include package versions, none of the static script tags provides a Subresource Integrity hash. The dynamic fallback loaders also cannot enforce SRI as written. Versioned CDN URLs reduce accidental version drift but do not independently verify the exact bytes returned to the browser. A compromised CDN account, package publication, distribution endpoint, DNS path, or upstream artifact can therefore replace the expected library with malicious JavaScript. The three-source fallback in `preview-template.html` ...[truncated 1244 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bundle reviewed JavaScript dependencies with the Skill so reports do not fetch executable code at view time. 2. If external hosting is unavoidable, add verified Subresource Integrity hashes: ```html <script src="https://cdn.example.invalid/library.min.js" integrity="sha384-REPLACE_WITH_VERIFIED_HASH" crossorigin="anonymous"> </script> ``` 3. Pin dependencies to immutable artifacts whose exact bytes are reviewed. 4. Remove multi-CDN executable fallback logic. Failure should disable optional export functionality rather than silently expanding trust to another source. 5. Add a Content Security Policy limiting script execution to bundled or integrity-approved resources. 6. Maintain dependency inventories and periodically review the pinned versions for known vulnerabilities. 7. Ensure report viewing remains functional offline, which avoids runtime dependency substitution and improves availability. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (50)

Tainted flow: 'req' from os.environ.get (line 312, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
ssl_ctx.verify_mode = ssl.CERT_NONE

    try:
        with urllib.request.urlopen(req, context=ssl_ctx, timeout=30) as resp:
            result = json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        raise Exception(f"HTTP请求失败: {e.code}, {e.read().decode('utf-8', errors='replace')}")
Confidence
97% confidence
Finding
The request includes an API key sourced from environment/shell configuration and is sent over HTTPS with certificate validation explicitly disabled. That means a man-in-the-middle on the network can intercept or modify the request and steal the credential, so the tainted flow to network is materially dangerous in this context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares no permissions, yet its instructions clearly require network access, reading environment variables and shell startup files, and writing local files. This breaks least-privilege expectations and can surprise users or hosts into granting broad capabilities that expose credentials and local data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill says '严禁任何联网搜索' while depending on requests and instructing calls to an external Redfox API, and it also reads local shell config files and writes reports to disk. This mismatch can mislead users and security controls about what the skill actually does, increasing the risk of unauthorized network use, credential access, and local data modification.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The README states '严禁任何联网搜索' while simultaneously requiring an external Redfox API key and directing the skill to fetch data from redfox.hk. This creates a deceptive or contradictory operating model that can mislead users, reviewers, or policy enforcement into believing the skill is offline-only when it actually depends on network access and third-party services.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
Instructing the agent to scan ~/.zshrc, ~/.bashrc, ~/.profile, and similar files to extract API keys expands the skill from content analysis into local secret discovery. Shell startup files often contain unrelated tokens, credentials, and personal configuration, so broad file reads create unnecessary exposure of sensitive data.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill requires creating host-level scheduled subscriptions based on query conditions, which introduces persistent automation beyond a one-time inspiration/query function. Persistent jobs can continue running, access future data, and generate ongoing notifications or network activity without clear bounded consent.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Recurring leaderboard subscriptions similarly broaden the skill into ongoing automation not clearly covered by the manifest purpose. This can lead to repeated background execution, extra API usage, and unintended persistence on the host.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Mandating a subscription service for account-benchmark queries adds persistence and host-level automation to a skill framed as a recommendation/query tool. Forced subscription behavior increases the chance of unintended scheduled tasks and ongoing data processing.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The template loads executable JavaScript from multiple third-party CDNs at runtime, which creates a supply-chain and privacy risk: anyone opening the generated HTML will make outbound requests and execute remotely hosted code. This also conflicts with the skill metadata stating '严禁任何联网搜索', making the network behavior unexpected in context and therefore more dangerous.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The skill metadata explicitly says '严禁任何联网搜索', yet this document specifies an external API request format and API-key-based access for fetching Xiaohongshu data. This mismatch can cause an agent or operator to invoke networked data retrieval despite the declared constraint, creating policy bypass risk and possible unauthorized outbound requests or data handling.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The workflow expands the skill from on-demand inspiration retrieval into an unsolicited subscription/push service, which changes the trust boundary and creates a persistent action channel not clearly reflected in the skill’s declared scope. That increases the risk of unexpected outbound behavior, user surprise, and misuse of the agent to perform ongoing actions without sufficiently explicit consent and lifecycle controls.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The instructions tell the agent to persistently modify shell startup files or Windows user environment settings to install API credentials. This is dangerous because it causes long-lived system configuration changes and secret persistence on the user’s machine, potentially exposing credentials to other processes, future sessions, logs, or accidental disclosure, and it exceeds a normal read-only assistant boundary.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The document explicitly directs use of an external HTTPS API endpoint even though the skill metadata states '严禁任何联网搜索'. That creates a direct policy/behavior mismatch: an agent implementing this skill could make outbound network calls contrary to the declared constraint, enabling unauthorized data egress or remote dependency use.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The Python example contains runnable code that performs a live outbound HTTP POST to a third-party endpoint, operationalizing the policy violation rather than merely describing it. In an agent-skill context, examples are often copied into implementation, so this materially increases the likelihood the agent will perform unauthorized network access.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The script intentionally scans local shell profile files to recover an API key if it is not present in the environment. Reading user dotfiles expands the skill's access to local secrets beyond what is necessary for a content-search helper and can unintentionally expose credentials stored in those files. In this skill context, that behavior is more dangerous because the manifest explicitly says networked search is forbidden, yet the script both harvests credentials and uses them for third-party access.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The manifest states '严禁任何联网搜索' but the script is built around sending requests to an external Redfox API endpoint. This is a direct policy and trust-boundary violation: user inputs and query metadata are transmitted to a third party despite the skill claiming not to perform networked search. In this context, the mismatch makes the behavior more dangerous because users or orchestrators may rely on the no-network claim when deciding whether the skill is safe to run.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The script goes beyond reading a single environment variable and actively scans local shell/profile files to recover API credentials, then injects the recovered value back into the process environment. For a Xiaohongshu inspiration aggregation skill, this is over-broad local secret access and creates unnecessary exposure of sensitive credentials from unrelated user configuration files.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The script goes beyond its stated purpose of fetching ranking data by reading local shell profile files to recover credentials. Even though it only targets a specific key name, this is sensitive local file access and can expose secrets from user configuration files without clear necessity or consent.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script reads shell profile files to scrape an API key if the environment variable is unset. Accessing user shell initialization files is broader than necessary for this task and expands the skill's access to unrelated local secrets and configuration data, which is especially risky in an agent context.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill metadata explicitly says '严禁任何联网搜索', yet the implementation performs outbound HTTPS requests to redfox.hk. This contradiction is dangerous because it defeats operator expectations and can cause unintended data disclosure of user-supplied queries, metadata, and credentials to an external service.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill metadata explicitly says '严禁任何联网搜索', yet the script performs outbound HTTPS requests to redfox.hk and also embeds external CDN JavaScript in the generated HTML. In this skill context, hidden or contradictory network access is especially dangerous because users may rely on the manifest constraint when deciding whether to trust and run the tool.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The script reads credentials not only from a dedicated environment variable but also scans user shell startup files for exported secrets. This exceeds least-privilege expectations for an HTML generation utility and can expose unrelated secrets or normalize unsafe credential harvesting behavior if the code is modified or reused.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The script presents itself as a local HTML report generator, but the generated report includes a remote script from jsDelivr. Opening the report in a browser will trigger a network request to a third party, which breaks the local-only expectation and exposes metadata such as IP, user agent, and access timing; if the CDN content is unavailable or compromised, report functionality can also be affected.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The generated HTML explicitly loads html2canvas from a public CDN, causing outbound network access when the report is viewed. In this skill's context, the metadata says '严禁任何联网搜索', so introducing a browser-time external dependency is especially risky because it violates the declared offline/no-network constraint and creates an unreviewed third-party trust boundary.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The script reads shell startup files such as .zshrc and .bashrc to extract REDFOX_API_KEY, which expands its access beyond the minimum needed for content retrieval. Even though it looks only for one variable, this behavior accesses sensitive local configuration files and creates an unnecessary secret-harvesting pattern in a skill that users may not expect to inspect personal shell profiles.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.insecure_tls_verification

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/gen_xhs_html.py:68

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/xhs_daily_fetcher.py:66

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/fetch_explosive_articles.py:272

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/xiaohongshu-similar-account.py:310