Back to skill

Security audit

小红书操作全集 Xiaohongshu All In One 基于api接口稳定快速

Security checks for vulnerabilities and agentic risk

Overview

This skill largely does what it says, but it can run unverified downloaded binaries, store account cookies in plaintext, and perform real account/platform actions with limited safeguards.

Review carefully before installing. Use only in a dedicated directory and preferably a test account, do not store or share the cookie JSON files casually, avoid running it with elevated privileges, and treat MCP download/start/restart as execution of unverified third-party native code. Confirm the target account and content before any publish, comment, logout, or account-switch action.

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

T03 · Remote Payload Retrieval and Execution

Error
Location
src/xiaohongshu_aio/mcp_service.py:108
Finding

Unverified Remote Release Binaries Are Downloaded and Executed

Content
View full analysis

Vulnerability Details

File Location: src/xiaohongshu_aio/mcp_service.py:25-26, 108-119, 155-207, 334-374
Vulnerability Type: Remote payload retrieval and execution without integrity verification
Risk Level: High

Vulnerable Code

python
GITHUB_REPO = "xpzouying/xiaohongshu-mcp"
GITHUB_API_RELEASES = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest"
python
def get_release_assets(self) -> dict:
    """Get release assets from GitHub API

    Returns:
        Dict mapping asset names to download URLs
    """
    request = Request(GITHUB_API_RELEASES)
    request.add_header("Accept", "application/vnd.github.v3+json")

    try:
        with urlopen(request, timeout=30) as response:
            data = json.loads(response.read().decode("utf-8"))
            assets = data.get("assets", [])
            return {asset["name"]: asset["browser_download_url"] for asset in assets}
    except (URLError, HTTPError) as e:
        raise RuntimeError(f"Failed to fetch release assets: {e}")
python
print(f"Downloading: {server_url}")
if not self.download_file(server_url, server_path):
    return False

print("Extracting files...")
try:
    if server_file.endswith(".zip"):
        import zipfile
        with zipfile.ZipFile(server_path, "r") as zip_ref:
            zip_ref.extractall(self.work_dir)
    else:
        with tarfile.open(server_path, "r:gz") as tar:
            tar.extractall(self.work_dir)
    server_path.unlink()
except Exception as e:
    print(f"Extraction failed: {e}")
    return False

if self.os_type != "windows":
    server_path = self._get_server_path()
    login_path = self._get_login_path()
    if server_path.exists():
        server_path.chmod(server_path.stat().st_mode | 0o755)
    if login_path.exists():
        login_path.chmod(login_path.stat().st_mode | 0o755)
python
if background:
    log_path 
...[truncated 2799 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin an explicitly audited release version instead of resolving releases/latest at runtime.
  2. Maintain an allowlisted mapping of supported platform assets and their expected SHA-256 digests.
  3. Verify the digest before archive extraction and fail closed if it does not match.
  4. Prefer cryptographically signed release manifests and verify signatures against a key distributed independently of the downloaded release.
  5. Reject unexpected asset names, duplicate matches, and redirects to origins outside a strict allowlist.
  6. Download into a newly created private temporary directory rather than directly into the execution directory.
  7. Verify that the archive contains only the exact expected files before making anything executable.
  8. Require explicit user confirmation before first execution of a newly downloaded binary.
  9. Record the verified release version and digest for auditability.

T09 · Insecure Skill Coding Practices

Error
Location
src/xiaohongshu_aio/mcp_service.py:187
Finding

Downloaded Archives Are Extracted Without Path or Link Validation

Content
View full analysis

Vulnerability Details

File Location: src/xiaohongshu_aio/mcp_service.py:187-195
Vulnerability Type: Archive path traversal and unsafe link extraction
Risk Level: High

Vulnerable Code

python
print("Extracting files...")
try:
    if server_file.endswith(".zip"):
        import zipfile
        with zipfile.ZipFile(server_path, "r") as zip_ref:
            zip_ref.extractall(self.work_dir)
    else:
        with tarfile.open(server_path, "r:gz") as tar:
            tar.extractall(self.work_dir)
    server_path.unlink()
except Exception as e:
    print(f"Extraction failed: {e}")
    return False

Technical Analysis

The downloaded archive is extracted directly into work_dir with extractall() and no inspection of member paths or types.

A malicious archive can contain absolute paths, .. traversal components, or links that resolve outside the intended destination. Because the package supports Python versions beginning at 3.10, it cannot assume that modern safe TAR extraction filters are available or enabled. ZIP entries likewise require explicit containment validation.

This issue compounds the unverified-download vulnerability: control over the release archive may allow an attacker to write files outside the MCP working directory even before the expected server executable is started.

Attack Path

  1. An attacker gains control of a release archive selected by download_binaries().
  2. The archive includes a member such as ../../.config/example, an absolute path, or a symbolic or hard link targeting a file outside work_dir.
  3. A user or Agent runs xhs mcp download.
  4. extractall(self.work_dir) processes the malicious member without containment checks.
  5. The member overwrites or creates a file elsewhere in the invoking user's writable filesystem.
  6. If the target is an automatically loaded configuration or executable file, the malicious content may execute lat ...[truncated 531 chars]
Remediation
View remediation

Remediation Suggestions

  1. Extract archives into a newly created private staging directory.
  2. For every archive member, resolve the proposed destination and verify that it remains beneath the staging directory.
  3. Reject absolute paths and any member containing a .. path component.
  4. Reject device files, FIFOs, and other special file types.
  5. Reject symbolic and hard links, or verify that both the link and its resolved target remain inside the extraction root.
  6. On Python versions supporting it, use tar.extractall(path, filter="data") in addition to explicit expected-file validation.
  7. Apply equivalent containment checks to ZIP members before extraction.
  8. Require an exact allowlist of expected filenames and reject extra archive contents.
  9. Move verified files atomically from the staging directory into their final locations.

T09 · Insecure Skill Coding Practices

Error
Location
src/xiaohongshu_aio/account.py:34
Finding

Reusable Authentication Cookies Are Stored in Plaintext With Unrestricted Default Permissions

Content
View full analysis

Vulnerability Details

File Location: src/xiaohongshu_aio/account.py:34-41, 73-82, 87-96
Vulnerability Type: Insecure storage of authentication material
Risk Level: High

Vulnerable Code

python
def _save_user_cookies(self) -> None:
    """Save user cookies to file"""
    data = {
        "accounts": self.accounts,
        "current_account": self.current_account
    }
    with open(self.user_cookies_path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
python
def switch_account(self, username: str) -> bool:
    """Switch to another account"""
    if username not in self.accounts:
        return False

    # Write cookies to mcp cookies.json
    cookies = self.accounts[username]["cookies"]
    try:
        with open(self.cookies_json_path, "w", encoding="utf-8") as f:
            json.dump(cookies, f, ensure_ascii=False, indent=2)

        # Update last used time
        self.accounts[username]["last_used"] = datetime.now().isoformat()
        self.current_account = username
        self._save_user_cookies()
        return True
    except Exception:
        return False
python
def import_cookies(self, username: str, notes: str = "") -> bool:
    """Import cookies from mcp cookies.json"""
    if not os.path.exists(self.cookies_json_path):
        return False

    try:
        with open(self.cookies_json_path, "r", encoding="utf-8") as f:
            cookies = json.load(f)

        self.add_account(username, cookies, notes)
        return True
    except Exception:
        return False

Technical Analysis

Authentication cookies are saved as plaintext JSON in both user_cookies.json and the MCP server's cookies.json. The files are opened using ordinary "w" mode, so their permissions depend on the process umask. The implementation does not create new files with owner-only permissions ...[truncated 1704 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store authentication material in the operating system's credential manager or keyring where available.
  2. If file storage is unavoidable, place the files in a dedicated per-user configuration directory that is not the current project directory.
  3. Create new files atomically with owner-only mode 0600 on POSIX systems.
  4. Inspect and correct permissions on existing cookie files before reading or writing them.
  5. Ensure the parent directory is owner-only, such as mode 0700.
  6. Avoid duplicating complete cookie sets across multiple files.
  7. Use temporary files with restrictive permissions, flush and synchronize them, and atomically replace the destination.
  8. Add cookie files to source-control and packaging exclusion rules.
  9. Provide a secure deletion and session-revocation workflow when an account is removed.
  10. Warn users if a selected path is group-writable, world-writable, shared, or located inside a source repository.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
src/xiaohongshu_aio/mcp_service.py:252
Finding

Service Management Can Forcibly Terminate Unrelated Processes

Content
View full analysis

Vulnerability Details

File Location: src/xiaohongshu_aio/mcp_service.py:252-325, 376-405
Vulnerability Type: Insufficient process identity validation before destructive signaling
Risk Level: Medium

Vulnerable Code

python
def check_process_running(self, process_name: str = "xiaohongshu-mcp") -> Optional[int]:
    """Check if process is running

    Args:
        process_name: Process name to search for

    Returns:
        PID if process is running, None otherwise
    """
    try:
        if self.os_type == "windows":
            result = subprocess.run(
                ["tasklist", "/FI", f"IMAGENAME eq {process_name}*", "/FO", "CSV", "/NH"],
                capture_output=True,
                text=True,
                timeout=10
            )
            for line in result.stdout.split("\n"):
                if process_name in line.lower():
                    parts = line.split(",")
                    if len(parts) >= 2:
                        return int(parts[1].strip('"'))
        else:
            result = subprocess.run(
                ["pgrep", "-f", process_name],
                capture_output=True,
                text=True,
                timeout=10
            )
            if result.returncode == 0 and result.stdout.strip():
                return int(result.stdout.strip().split()[0])
    except (subprocess.TimeoutExpired, FileNotFoundError, ValueError):
        pass

    return None
python
def kill_process(self, pid: int) -> bool:
    """Kill process by PID

    Args:
        pid: Process ID to kill

    Returns:
        True if successful
    """
    try:
        if self.os_type == "windows":
            subprocess.run(["taskkill", "/F", "/PID", str(pid)], timeout=10)
        else:
            os.kill(pid, signal.SIGKILL)
        return True
    except (ProcessLookupError, PermissionError, subprocess.Ti
...[truncated 3269 chars]
Remediation
View remediation

Remediation Suggestions

  1. Save the exact child PID when starting the service in an owner-only PID file.
  2. Store additional identity information such as executable path and process start time to defend against PID reuse.
  3. Before signaling, verify that the PID belongs to the current user and that its executable resolves to the expected server binary.
  4. Do not automatically kill an arbitrary process merely because it owns port 18060.
  5. If the configured port is occupied by another process, report the conflict and require explicit user intervention.
  6. Attempt graceful shutdown with SIGTERM or the service's shutdown API before using a forceful signal.
  7. Use SIGKILL only after a bounded grace period and only for a positively identified owned child.
  8. On Windows, verify executable identity before invoking taskkill.
  9. Remove stale PID files safely and handle process-reuse races.
  10. Warn users against running service-management commands with elevated privileges.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The description and code are largely aligned on the main purpose: Xiaohongshu MCP service management, multi-account handling, login management, publishing content, querying feeds/users, and comment interactions. However, there is a notable description-behavior mismatch because the description explicitly claims 点赞/like support, but this code chunk only implements comment and reply interactions—no like action is exposed. There are also some extra implemented CLI actions (e.g., stop/test/logout/import/current) not called out in the description, though these are adjacent rather than unrelated. Because an explicitly declared user-facing capability appears absent from the supplied code chunk, this should be flagged as a mismatch, albeit a partial one rather than a wholly different purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code generally aligns with part of the description: it does support login-related checks, content publishing, feed/note retrieval, user info lookup, and commenting. However, the declared purpose is materially broader than what this code chunk actually does. This client does not implement MCP service download/start/restart/detection, does not provide multi-account management, and does not implement like operations. Since the description presents these as capabilities requiring this skill, but the supplied code chunk lacks them, the description does not accurately represent the actual behavior of this specific code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description claims a comprehensive Xiaohongshu operational skill covering account management, login, publishing, engagement actions, and data retrieval. However, this code chunk is narrowly focused on MCP service management: downloading binaries from GitHub, extracting them, checking whether the service is running, managing the process/port, and testing connectivity to a local MCP endpoint. While the description does mention download/start/restart/detection, the majority of the advertised end-user capabilities are not present in this code. This is a material description-versus-behavior mismatch because the actual primary purpose of this chunk is infrastructure/service management rather than Xiaohongshu account/content/data operations.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The code directly executes a local binary with os.execv after downloading and extracting release artifacts from GitHub, replacing the current process without additional integrity verification or user confirmation. In this skill's context, that creates a real supply-chain and arbitrary code execution risk if the release asset, repository, or local working directory contents are tampered with.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 374)May include surrounding context.

python
return False
        else:
            os.chdir(self.work_dir)
            os.execv(str(server_path), [str(server_path)])
    
    def stop_service(self) -> bool:
        """Stop MCP service

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README explicitly promotes cookie import/export and references local cookie storage, but does not warn that cookies are authentication secrets equivalent to active session tokens. In a multi-account automation/publishing tool, mishandling exported cookies can enable account takeover, unauthorized posting, or profile access if the file is copied, logged, shared, or committed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The README advertises commands that can log out accounts, remove account data, publish content, post comments, and control the MCP server, but it does not clearly warn that these actions are destructive or externally visible. In an agent-skill context, this increases the risk of accidental execution causing service disruption, account state changes, spammy platform activity, or unintended public posting.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

README 明确介绍了导入/导出 cookies、账号切换,以及项目目录中的 user_cookies.json 本地存储,但没有任何关于这些 cookies 属于高敏感认证材料、可能导致账号接管、以及不应明文共享或提交到版本库的警示。在该技能场景下,cookies 直接对应小红书多账号登录态,用户容易把它当作普通配置文件处理,从而扩大泄露风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

README 将发布笔记/视频、评论、回复、点赞等会对外部平台和真实账号产生不可逆影响的操作描述为常规功能,但缺少显著提示,未提醒用户这些命令可能导致误发内容、批量互动、账号风控或合规问题。由于这是一个面向多账号管理和自动化交互的技能,缺乏风险告知会使误操作和滥用更现实。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises and documents shell, network, and file-manipulating operations but does not declare any explicit tool scope or allowed-tools boundaries. In an agent environment, that omission can let the skill be invoked with broader capabilities than necessary, increasing the risk of unintended command execution, file access, or outbound requests against user-controlled targets such as the configured MCP URL.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation language is very broad: it says the skill should be called whenever a user needs many kinds of Xiaohongshu actions or data access. Overbroad triggers can cause an agent to invoke a high-impact skill in ordinary conversations, leading to unnecessary shell/network actions, account manipulation, publishing, or data access without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill describes account switching and content publishing workflows without prominent confirmation or safety gating for actions that change account state and perform external actions on the user's behalf. In an agent setting, this increases the chance of accidental posting, interacting, or switching identities using stored cookies, which can directly affect user accounts and third-party platforms.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code persists account cookie material directly to user_cookies.json in plaintext, which stores active session secrets for multiple Xiaohongshu accounts. If the local filesystem is accessed by another user, malware, backups, or logs, these cookies could be reused to hijack accounts without needing credentials. In this skill context, the risk is elevated because the module explicitly manages multiple accounts and session cookies as part of its core workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

switch_account() overwrites cookies.json with the selected account's live cookies, meaning sensitive session tokens are copied into another plaintext file as part of account switching. This increases exposure by duplicating secrets and may cause accidental use, leakage, or cross-account confusion by other components that read cookies.json, especially in a multi-account automation tool where account separation matters.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The client defaults to an insecure HTTP base URL while handling sensitive actions such as login status checks, profile access, content publishing, and comment operations. In the context of a social-media automation skill, this can expose session data, account metadata, and published content to interception or tampering if the service is not strictly confined to localhost or if the base URL is overridden via environment variables.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The delete_cookies method performs a DELETE request to remove login cookies, which is a potentially destructive session-impacting action. There is no confirmation prompt, user-facing log message, or warning in the method docstring beyond the bare action name.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 27)May include surrounding context.

python
MCP_PORT = 18060
GITHUB_REPO = "xpzouying/xiaohongshu-mcp"
GITHUB_API_RELEASES = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest"


class MCPServiceManager:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code downloads an archive from release assets, extracts it into the working directory, and later executes binaries from that location without explicit integrity validation or strong user warning. This is dangerous because a compromised upstream release, malicious archive contents, or path traversal during extraction can lead to arbitrary file overwrite and code execution.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 225)May include surrounding context.

python
"""
        try:
            if self.os_type == "windows":
                result = subprocess.run(
                    ["netstat", "-ano"],
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 237)May include surrounding context.

python
if parts:
                            return int(parts[-1])
            else:
                result = subprocess.run(
                    ["lsof", "-ti", f":{port}"],
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 261)May include surrounding context.

python
"""
        try:
            if self.os_type == "windows":
                result = subprocess.run(
                    ["tasklist", "/FI", f"IMAGENAME eq {process_name}*", "/FO", "CSV", "/NH"],
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 273)May include surrounding context.

python
if len(parts) >= 2:
                            return int(parts[1].strip('"'))
            else:
                result = subprocess.run(
                    ["pgrep", "-f", process_name],
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
84% confidence
Finding

This code forcibly terminates a PID using taskkill based on prior detection logic, with no validation that the process is the intended MCP service. If PID resolution is wrong or an attacker intentionally occupies the target port, the skill can kill unrelated local processes, causing denial of service or operational disruption.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 297)May include surrounding context.

python
"""
        try:
            if self.os_type == "windows":
                subprocess.run(["taskkill", "/F", "/PID", str(pid)], timeout=10)
            else:
                os.kill(pid, signal.SIGKILL)
            return True

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The function frees the service port by killing whatever process is currently bound to it, without ensuring it is the MCP service. In this skill context, that can disrupt unrelated applications and gives an attacker a trivial way to trigger targeted local denial of service by binding the expected port first.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The service start path launches a background subprocess from a local binary, but the code provides no explicit warning that executable code will run detached in the background. Combined with the binary download flow, this increases the risk of unnoticed execution of untrusted code on the host.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

This launches a binary from the working directory in the background via subprocess.Popen. Because the binary may have been downloaded earlier and there is no signature or checksum verification, this creates a realistic arbitrary code execution path through trojanized release assets or local file replacement.

Content

Scanner excerpt · src/xiaohongshu_aio/mcp_service.py (reported line 345)May include surrounding context.

python
if background:
            log_path = self.work_dir / "mcp.log"
            if self.os_type == "windows":
                subprocess.Popen(
                    [str(server_path)],
                    stdout=open(log_path, "w"),
                    stderr=subprocess.STDOUT,

Static analysis

No suspicious patterns detected.