Back to skill

Security audit

小红书

Security checks for vulnerabilities and agentic risk

Overview

This XiaoHongShu automation skill needs Review because it uses session cookies, can change account state, and includes underdocumented engagement and anti-abuse handling code.

Only install after reviewing the code and accepting the account and platform-policy risks. Treat web_session as a password-equivalent secret, avoid putting it in chats or logs, remove or disable the read-count metrics flow, add explicit confirmation for all follow/like/comment/delete actions, replace eval() config parsing, redact cookies from logs, and pin dependencies before use.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/request/web/xhs_session.py:199
Finding
Authentication Cookie Exposed in Application Logs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/request/web/xhs_session.py`, lines 199-200 and 242-270 **Vulnerability Type**: Sensitive authentication data exposure through logging **Risk Level**: High ### Vulnerable Code ```python cookies_dict = {cookie.key: cookie.value for cookie in self._session.cookie_jar} web_session = cookies_dict.get('web_session') ``` The credential is subsequently included verbatim in multiple log messages: ```python if "禁言" in msg_lower or "被禁言" in msg_lower: logger.warning(f"禁言 | {web_session} | {res_msg} | {logger_info}") raise session_exceptions.MutedError(res_msg) elif "登录已过期" in res_text_lower or "登录超时" in msg_lower: logger.warning(f"掉线 | {web_session} | web_session 登录超时 | {logger_info}") raise session_exceptions.LoginTimeOut(res_msg) elif "删除" in res_text_lower: logger.warning(f"笔记/评论被删除 | {logger_info}") raise session_exceptions.TaskDeleteError(res_msg) elif "无权限访问" in msg_lower: logger.warning(f"过期 | {web_session} | web_session 没有权限访问 | {logger_info}") raise session_exceptions.PermissionError(res_msg) elif "违规情形" in msg_lower or "被封号" in msg_lower or "封号" in msg_lower: logger.warning(f"封号 | {web_session} | {res_msg} | {logger_info}") raise session_exceptions.BannedError(res_msg) elif "用户已关闭评论艾特" in msg_lower: logger.warning(f"用户已关闭评论艾特 | {logger_info}") raise session_exceptions.UserCloseCommentAtError(res_msg) elif "对方设置" in msg_lower or "无法发布评论" in msg_lower: logger.warning(f"对方设置你无法评论 | {logger_info}") raise session_exceptions.CantCommentError(res_msg) elif "blockedps" in res_text_lower: logger.warning(f"封号 | {web_session} | blockedPs | {logger_info}") raise session_exceptions.BannedError(res_msg) ``` ### Technical Analysis The `web_session` value is an authentication credential supplied by the user and stored in the HTTP cookie jar. Several routine error-handling branches interpolate the complete credential into Loguru messages. Lo ...[truncated 1694 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `web_session` from every log message. Log only the error class, response status, endpoint, and a non-sensitive request identifier. 2. If correlation is essential, derive a short one-way fingerprint using a dedicated keyed hash. Never log a raw or reversibly encoded credential. 3. Add a centralized logging filter that redacts cookie names such as `web_session`, `a1`, `webId`, and authorization-related headers. 4. Avoid placing complete request headers, cookies, or response objects in exception logs. 5. Define and enforce short retention periods and restrictive access controls for existing logs. 6. Rotate or invalidate credentials that may already have appeared in logs. 7. Add automated tests that inject sentinel credentials and verify that they never appear in captured logging output. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/request/web/encrypt/config.py:12
Finding
Arbitrary Python Code Execution Through Configuration Evaluation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/request/web/encrypt/config.py`, lines 12-16 **Vulnerability Type**: Unsafe evaluation of configuration data **Risk Level**: Medium ### Vulnerable Code ```python def get(self, section: str, key: str, fallback=None): """ 获取配置项的通用方法 """ return eval(self.config.get(section, key, fallback=fallback)) ``` ### Technical Analysis The configuration accessor passes every retrieved INI value to Python's unrestricted `eval()` function. `eval()` treats configuration text as executable Python expressions rather than inert data. The bundled `web_encrypt_config.ini` currently contains literals such as strings, integers, lists, and dictionaries. However, if that file is modified, replaced, or sourced from a compromised package, an attacker can insert expressions that import modules, access files, launch processes, or perform network operations. The expression executes whenever the affected key is retrieved. The vulnerability is especially significant because configuration retrieval occurs during module initialization and construction of encryption components. A malicious expression may therefore execute as a normal side effect of importing or initializing the Skill. ### Attack Path 1. An attacker gains the ability to modify `scripts/request/web/encrypt/web_encrypt_config.ini`, replace the Skill package, or influence how that configuration is deployed. 2. The attacker replaces a configuration value with a Python expression containing a malicious payload. 3. The Skill imports `xhs_config` and an encryption or request component calls `xhs_config.get(...)`. 4. `Config.get()` passes the attacker-controlled expression to `eval()`. 5. Python executes the expression with the same operating-system identity and privileges as the Agent process. 6. The payload can access any files, environment variables, network resources, or subprocess capabilities available to that process. ### Impact Assessment Succes ...[truncated 561 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace unrestricted `eval()` with `ast.literal_eval()` if compatibility with Python literal syntax is required: ```python import ast def get(self, section: str, key: str, fallback=None): value = self.config.get(section, key, fallback=fallback) return ast.literal_eval(value) ``` 2. Prefer explicit typed accessors rather than a generic evaluator: - `config.get()` for strings - `config.getint()` for integers - `config.getboolean()` for booleans - JSON parsing for lists and dictionaries 3. Validate each setting against an allowlisted schema, including expected type, length, character set, and permitted URL host. 4. Fail closed on malformed or missing values instead of evaluating fallback text. 5. Protect the configuration file with restrictive filesystem permissions and package-integrity verification. 6. Add tests proving that expressions containing imports, function calls, and attribute access are rejected without execution. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:13
Finding
Unpinned Third-Party Dependency Installation Creates Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 13-17 and 275-278 **Vulnerability Type**: Unpinned dependencies installed from an unspecified package source **Risk Level**: Medium ### Vulnerable Code Installation instructions: ```bash pip install aiohttp loguru pycryptodome getuseragent ``` The same unrestricted command is repeated in troubleshooting guidance: ```bash pip install aiohttp loguru pycryptodome getuseragent ``` ### Technical Analysis The documentation directs users to install mutable package names without exact versions, integrity hashes, a lockfile, or an explicitly trusted package index. Dependency resolution therefore depends on the package index and resolver state at installation time. A future compromised release, compromised package-index account, malicious mirror, resolver misconfiguration, or incompatible update could introduce code that executes during installation or import. This is particularly relevant because the Skill imports these packages directly, and Python packages can execute arbitrary module-level code. The audit did not establish that any named dependency is currently malicious. The confirmed issue is the absence of reproducible and integrity-verified dependency controls. ### Attack Path 1. A user follows the documented `pip install` command. 2. `pip` resolves the latest acceptable versions using the environment's configured package index or mirror. 3. A dependency or its transitive dependency has been compromised, substituted by an unsafe mirror, or changed incompatibly since the Skill was reviewed. 4. The package is downloaded without verification against project-maintained hashes. 5. Malicious installation hooks or imported module code execute with the installing or Agent user's privileges. 6. The dependency can access local data and network resources available to the Python process. ### Impact Assessment A compromised dependency can obtain arbitrary code execution with the privileges of ...[truncated 455 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct and transitive dependency to a reviewed version in a lockfile. 2. Generate and require cryptographic hashes, for example through a requirements file used with `pip install --require-hashes`. 3. Specify and document the trusted package index rather than inheriting an arbitrary environment configuration. 4. Regularly scan pinned dependencies for known vulnerabilities and review updates before changing the lockfile. 5. Install dependencies in an isolated virtual environment with only the permissions required by the Skill. 6. Reconcile the statement that dependencies are already installed with the instruction to run `pip install`; remove installation instructions if package installation is not necessary. 7. Consider distributing a reproducibly built, signed environment or package artifact. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The supplied code is only a minimal module aggregator that instantiates Authentication, Comments, Note, and User API wrappers with a session. It does not itself implement or demonstrate most of the specific declared XiaoHongShu capabilities, such as searching, feed retrieval, likes/follows interactions, or automatic encryption/header handling. While the module names are broadly consistent with parts of the declared purpose (auth, comments, notes, users), the chunk is too limited to substantiate the full description. Therefore the description overstates what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description focuses on content/data collection and social interactions on XiaoHongShu (searching notes, scraping posts, retrieving profiles/comments/likes, following users, liking posts, and fetching feeds). However, the supplied code is specifically for authentication workflows, including creating and polling QR login sessions, handling a security QR verification process, and sending SMS login codes. Those are materially different capabilities not disclosed in the description. One function to fetch the current user's own basic info is adjacent to session/auth management, but the primary purpose of this code chunk is authentication rather than data collection or content interaction. Therefore the description does not accurately represent this code chunk's actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a full-featured XiaoHongShu data collection and interaction toolkit. The supplied code chunk does not implement any of those capabilities; it merely defines a generic response data model for wrapping API results. This is a materially different primary purpose, so the description does not accurately represent the behavior of the provided code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a full XiaoHongShu scraping and interaction toolkit with platform-specific request signing, cookies, headers, and authenticated/guest session support. The supplied code chunk does none of that. It is limited to standalone utility functions for Base64, hex, and URL encoding/decoding. While such helpers could be supporting internals in a larger system, this specific chunk by itself does not implement or evidence the described platform functionality. Therefore the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a full XiaoHongShu scraping and interaction toolkit with platform-specific request signing/session handling. The supplied code chunk does not implement any of those capabilities. It only provides generic cryptographic hash/checksum helper functions, which may be a low-level support utility but, by itself, materially fails to represent the declared primary purpose. Therefore this chunk does not accurately match the description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a full-featured XiaoHongShu scraping and interaction toolkit with platform-specific request/signature handling. The supplied code chunk only implements a standard singleton pattern utility and contains none of the described behaviors. This is a clear material mismatch in primary purpose and actual capabilities.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The add_note_readnum routine is explicitly designed to fabricate engagement by fetching the viewer identity, reporting a note-entry event, optionally waiting a randomized dwell time, and then reporting an exit event to simulate a real read. In the context of a XiaoHongShu automation skill, this is not merely analytics handling but a mechanism to manipulate platform metrics, which can enable fraud, evasion of platform integrity controls, and deceptive amplification.

eval() call detected

High
Category
Dangerous Code Execution
Content
"""
        获取配置项的通用方法
        """
        return eval(self.config.get(section, key, fallback=fallback))

# 单例模式
xhs_config = Config()
Confidence
99% confidence
Finding
The code calls eval() on a value read from an INI configuration file, which can execute arbitrary Python expressions rather than just parsing data. If an attacker can modify the config file, influence its contents, or cause the application to load an untrusted config, this becomes arbitrary code execution in the context of the running process. In this skill's context, which handles authenticated sessions, cookies, encryption parameters, and scraping/interaction logic, successful exploitation could expose secrets or fully compromise the host running the skill.

Obfuscated Code

High
Category
Supply Chain
Content
# 使用示例
if __name__ == "__main__":
	# 假设这是编码后的p值
	encoded_p = "2UQAPsHC+aIjqArjwjHjNsQhPsHCH0rjNsQhPaHCH0c1Pjh9HjIj2eHjwjQgynEDJ74AHjIj2ePjwjQhyoPTqBPT49pjHjIj2ecjwjHFN0qEN0ZjNsQh+aHCH0rEw/HAwn+Y+Aqly9T64oGhyopdP0+hJnRU2oSl8BlD2gm92nQkqAbx+/ZIPeZl+eWEweqjNsQh+jHCHjHVHdW7H0ijHjIj2eWjwjQQPAYUaBzdq9k6qB4Q4fpA8b878FSet9RQzLlTcSiM8/+n4MYP8F8LagY/P9Ql4FpUzfpS2BcI8nT1GFbC/L88JdbFyrSiafp/cDMra7pFLDDAa7+8J7QgabmFz7Qjp0mcwp4fanD68p40+fp8qgzELLbILrDA+9p3JpH9LLI3+LSk+d+DJfpSL98lnLYl49IUqgcMc0mrcDShtMmozBD6qM8FyFSh8o+h4g4U+obFyLSi4nbQz/+SPFlnPrDApSzQcA4SPopFJeQmzBMA/o8Szb+NqM+c4ApQzg8Ayp8FaDRl4AYs4g4fLomD8pzBpFRQ2ezLanSM+Skc47Qc4gcMag8VGLlj87PAqgzhagYSqAbn4FYQy7pTanTQ2npx87+8NM4L89L78p+l4BL6ze4AzB+IygmS8Bp8qDzFaLP98Lzn4AQQzLEAL7bFJBEVL7pwyS8Fag868nTl4e+0n04ApfuF8FSbL7SQyrLUtASrpLS92dDFa/YOanS0+Mkc4FbQ4fSM+Bu6qFzP8oP9Lo4naLP78p+D+9pxcpPFaLp9qA++qDMFpd4panSDqA+AN7+hnDESyp8FGf+p8np8pd49ag88Gn+S8np/4g49/BEmqM+M4MmQ2BlFagYyL9RM4FRdpd4Iq7HFyBppN9L9/o8Szbm7zDS987PlqfRAPLzyyLSk+7+xGfRAP94UzDSbPBLALoz9anSjLDRl4FROqgziagYSq7Yc4A4QyrbSpSmFyrSiN7+8qgz/z7b72nMc4FzQ4DS3a/+Q4ezYzMPFnaRSygpFyDSkJgQQzLRALM8F2DQ6zDF6wg8Sy0Sy4DSkzLEo4gzCqdpFJrS94fLALozp/7mN8p88+g+nqBMTanYdqM8DPo+3Lozcqob7JFSePBLI4g4manTd8gYxLd4Q4fpSLAq68n8n4b+QPA4Ay7b74LEDLSmQyrYIaL+dq7Y+89p3GaRSnLc9qMSc4bbQyLF6a/+g/pkl4BbQPAzpanV98p4/qBlFy0pAPb8FqDS3pfSILoqMLBMw8n8gO/FjNsQhwaHCN/HM+AZM+eGUPaIj2erIH0iINsQhP/rjwjQ1J7QTGnIjKc=="

	# 解码
	decoded_p = decode_p(encoded_p)
Confidence
50% confidence
Finding
Code contains obfuscation (base64, hex encoding with execution). This is often used to hide malicious functionality.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The embedded x57 cookie string contains fixed real-session-style values such as a1 and webId, and x66 contains concrete navigation URLs unrelated to the function arguments. Hard-coding such state enables replay of captured session context and may support impersonation, bypass of anti-abuse controls, or unauthorized requests against the platform. Given this skill's stated purpose of automating encrypted XiaoHongShu interactions, the behavior is more dangerous than in a benign test harness.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The retry path automatically handles verification challenges by calling pass_scan_124 and then resubmitting the blocked request, effectively automating bypass of platform security checks. This is especially dangerous because it is triggered inside generic request handling, making challenge circumvention implicit and applicable to any downstream action performed by the skill.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documents clear network-capable behavior but does not declare any tool scope, permissions, or allowed-tools boundary. In an agent environment this weakens containment and transparency, making it easier for the skill to perform external requests without explicit review or restriction.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill encourages use of a web_session cookie for authenticated access and even shows example values, but it does not clearly warn that this is a sensitive session credential equivalent to account access. In agent settings, users may paste live cookies into prompts or configs, risking credential theft, account takeover, or accidental disclosure through logs and transcripts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill exposes follow and like operations without a prominent warning that these calls change the user's account state and may have reputational or policy consequences. In an autonomous or semi-autonomous agent context, missing consent guardrails can lead to unintended social actions, abuse complaints, or platform enforcement against the user account.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The send_code function accepts a phone number and sends it to a remote endpoint via an HTTP request. In this file there is no confirmation prompt, user disclosure, or warning that personal data will be transmitted over the network.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The function defaults the zone to "86" and the docstring says other countries are not currently supported, which imposes a specific locale without user opt-in or broader choice. This is a natural-language policy concern because the code and documentation hard-code a region-specific behavior rather than offering explicit language/locale selection.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
This code performs a destructive operation by deleting a comment via a POST request, but the method contains no confirmation prompt, user-facing warning, or explicit disclosure beyond a brief docstring name. For safety-critical irreversible actions, the file should make the destructive behavior clearly visible to callers or users.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The metrics reporting method sends viewer and author identifiers, request metadata, and interaction fields to a remote endpoint, but the file provides no user-facing confirmation, logging, or warning about this transmission. Because this is a code file, outbound transmission of user or system data should have some visible disclosure unless clearly covered elsewhere.

Intent-Code Divergence

Medium
Confidence
81% confidence
Finding
The function is documented as increasing a note's read count, but after sending the enter metrics event it randomly exits early half the time without sending the corresponding exit report or simulated dwell completion. This is an intent/documentation mismatch because the stated behavior is definitive while the code only probabilistically performs the full sequence.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code does more than omit disclosure: it actively performs remote telemetry submissions intended to artificially increase note read metrics, using randomized timing to better resemble genuine engagement. In a scraping/interaction toolkit, that makes the behavior more dangerous because it supports stealthy manipulation of platform signals at scale.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code accepts a user cookie value (`cookie_a1`) and embeds it into the generated `x-s-common` header payload, which is then encoded for outbound request use. Although this is central to the function's behavior, there is no user-facing warning, confirmation, or explicit disclosure in comments/docstrings that the skill processes authentication-related cookie data.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
Comments and code structure present the routine as a dynamic fingerprint generator using user_agent, cookies, randomization, and browser-like attributes, but the final reassignment discards those values and returns a static object instead. This deceptive implementation can mislead maintainers and downstream callers into believing the fingerprint is ephemeral and input-bound when it is actually replaying fixed state, undermining trust and masking riskier behavior.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The code fixes language and locale-related fields such as x3='zh-CN' and x12='Asia/Hong_Kong'/'Asia/Shanghai', forcing a specific language/region profile. This is a natural-language locale policy issue because the skill does not provide opt-in, fallback, or justification for constraining the generated profile to Chinese settings.

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
"x35": "0", # 判断是否加载 Modernizr 固定值
            "x36": f"{random.randint(1, 20)}", # 判断window.history.length 历史堆栈长度
            "x37": "0|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|1|0|0|0|0|0", # 环境监测 太长了懒得看 固定值
            "x38": "0|0|1|0|1|0|0|0|0|0|1|0|1|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0", # 环境监测 太长了懒得看 固定值
            "x39": 0, #小红书抽风这里写死成0了 f"{random.randint(1, 5)}", # localStorage.getItem('sc');  刷新一次页面 +1    1-5 随机即可 # 2025-9-7 18:17:39 注: 之前是p1 现在变成 sc
            "x40": "0", # localStorage.getItem('ptt');  但正常使用并无该值 固定0
            "x41": "0", # localStorage.getItem('pst');  但正常使用并无该值 固定0
Confidence
80% confidence
Finding
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
"x35": "0", # 判断是否加载 Modernizr 固定值
            "x36": f"{random.randint(1, 20)}", # 判断window.history.length 历史堆栈长度
            "x37": "0|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|1|0|0|0|0|0", # 环境监测 太长了懒得看 固定值
            "x38": "0|0|1|0|1|0|0|0|0|0|1|0|1|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0", # 环境监测 太长了懒得看 固定值
            "x39": 0, #小红书抽风这里写死成0了 f"{random.randint(1, 5)}", # localStorage.getItem('sc');  刷新一次页面 +1    1-5 随机即可 # 2025-9-7 18:17:39 注: 之前是p1 现在变成 sc
            "x40": "0", # localStorage.getItem('ptt');  但正常使用并无该值 固定0
            "x41": "0", # localStorage.getItem('pst');  但正常使用并无该值 固定0
Confidence
80% confidence
Finding
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/request/web/encrypt/config.py:16