Back to skill

Security audit

Xiaohongshu Parent FAQ Stills

Security checks for vulnerabilities and agentic risk

Overview

This skill is not plainly malicious, but it needs Review because it uses a broad shared Beatra credential and silently installs package updates by default.

Before installing, understand that this skill connects to a Beatra account, stores a shared local bearer credential, can spend Beatra credits after approval cards, uploads only user-selected files, and silently updates its own package by default. Review whether the broad Beatra authorization is acceptable for your environment and consider running the documented auto-update disable command if unattended code replacement is not allowed.

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
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:35
Finding
Overprivileged Shared Credential and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:35-39`; `scripts/mcp_client.py:1463-1482` **Vulnerability Type**: Violation of least privilege through excessive OAuth scopes and unrestricted tool selection **Risk Level**: High ### Complete Code Snippets `scripts/authorize.py:35-39`: ```python SCOPE = ( "mcp:tools artifacts:write images:generate videos:generate music:generate " "speech:generate voices:read voices:write wallet:spend tasks:read artifacts:read tasks:cancel" ) ``` `scripts/mcp_client.py:1463-1482`: ```python def _run_command(command: str, tool_name: str | None = None) -> dict[str, Any]: session = _session_with_registration( state_dir=Path.home() / ".beatra", post_json=_default_post_json, ) if command == "tools": return session.request(2, "tools/list", {}) try: arguments = json.load(os.sys.stdin) except json.JSONDecodeError as exc: raise RuntimeError("Tool arguments on stdin must be one JSON object") from exc if not isinstance(arguments, dict): raise RuntimeError("Tool arguments on stdin must be one JSON object") assert tool_name is not None return session.request( 2, "tools/call", {"name": tool_name, "arguments": arguments}, ) ``` ### Technical Analysis The Skill's declared workflow requires public Xiaohongshu note access, selected asset uploads, image generation or editing, task status reads, and billing information. The requested credential additionally grants unrelated capabilities for video, music, speech, and voice generation or modification. The credential is shared through `~/.beatra/credentials.json`. Although the implementation protects that file with restrictive POSIX permissions and transmits it only to a fixed HTTPS MCP endpoint, the authorization itself remains substantially broader than this Skill's legitimate requirements. The bundled client compounds this issue by accepting an arbitr ...[truncated 2002 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope credential with a package-specific credential containing only the capabilities required by this Skill. 2. Remove unrelated scopes, including video, music, speech, and voice generation or modification. 3. Separate read-only task and billing access from spending privileges where the service supports granular scopes. 4. Implement a package-local allowlist in `_run_command()`. Permit only the documented operations, such as the required model, social lookup, image, asset, task, wallet, and installation-registration calls. 5. Reject unknown tool names before creating an authenticated MCP session. 6. Consider separate explicit execution paths for paid operations, task cancellation, and read-only operations. 7. Enforce equivalent package-level restrictions on the server so bypassing the bundled client cannot restore broad access. 8. Add automated tests confirming that unrelated media, voice, administrative, or cancellation tools are rejected locally. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/mcp_client.py:969
Finding
Default Silent Retrieval and Installation of Remotely Controlled Executable Updates<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:969-1017`; supporting configuration at `scripts/mcp_client.py:31-32` and `scripts/mcp_client.py:520-522`; automatic invocation at `scripts/mcp_client.py:1542-1544` **Vulnerability Type**: Remote payload retrieval and executable package replacement **Risk Level**: Medium ### Complete Code Snippets `scripts/mcp_client.py:969-1017`: ```python def maybe_auto_update( *, state_dir: Path | None = None, install_root: Path | None = None, get_bytes: GetBytes = _default_get_bytes, now: float | None = None, ) -> bool: """Best-effort silent update. Never block the requested MCP command.""" resolved_state = state_dir or Path.home() / ".beatra" try: resolved_root = (install_root or _current_install_root()).resolve() update_home = _update_home(resolved_state, resolved_root) observed_at = time.time() if now is None else now nonce = _lock_update(update_home, now=observed_at) if nonce is None: return False try: recover_update(state_dir=resolved_state, install_root=resolved_root) state = _read_update_state(update_home) if state.get("auto_update", True) is False: return False last_checked = state.get("last_checked_at") if ( isinstance(last_checked, (int, float)) and observed_at - float(last_checked) < UPDATE_CHECK_MAX_AGE_SECONDS ): return False state["last_checked_at"] = observed_at _write_private_json(update_home / "state.json", state) checked = check_update(get_bytes=get_bytes) if not checked["update_available"]: return False _ensure_owned_baseline( install_root=resolved_root, update_home=update_home, get_bytes=get_bytes, ) discov ...[truncated 4451 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic update installation by default. 2. Permit silent update checks if desired, but require explicit user approval before downloading and replacing executable files. 3. Cryptographically sign each release with a dedicated offline package-signing key. 4. Embed or securely pin the corresponding verification public key in the audited client. 5. Verify the signed package identity, version, channel, locale, manifest digest, and archive digest before installation. 6. Protect signing and release authorization independently from the web and CDN publication systems so compromising those systems alone cannot produce a trusted release. 7. Display the current and proposed versions, release source, and changed executable files before approval. 8. Preserve the existing downgrade, path, size, ownership, locking, rollback, and recovery safeguards. 9. Provide an enterprise policy mechanism that forcibly disables self-modification. 10. Log update decisions and verified signer identity without recording credentials or sensitive user content. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises a narrow content-generation purpose but includes capabilities for shell, network, file read/write, and environment access without any declared permission model or clear minimization. That creates an overprivileged execution surface where a content task can invoke local and remote operations, increasing the risk of credential access, unintended file handling, and abuse of host resources if the bundled client or referenced workflows are compromised.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description frames the package as a simple Xiaohongshu FAQ still generator, but the body reveals much broader behavior: OAuth/device auth, persistent credential storage, remote tool invocation, local uploads, telemetry/registration, uninstall logic, and self-updating code. This mismatch prevents informed consent and can trick users or hosts into approving a package with materially more powerful and persistent behavior than disclosed.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill explicitly describes silent automatic updates that modify package-owned files without separate confirmation. Even with integrity checks, silent self-update introduces a software supply-chain and change-management risk: users may unknowingly run new code with the same local capabilities, and any compromise of the update channel or signing process would have immediate impact.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The document states that the client silently checks for updates by default and automatically installs newer versions without separate confirmation, which is system-modifying behavior with security and trust implications. Even though the text describes integrity checks and rollback protections, the lack of a prominent warning and opt-in consent means users may unknowingly execute code changes on their system, increasing risk if the update channel or signing assumptions are ever compromised.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The documentation describes automatic outbound registration on first use and creation of a local cache file containing installation metadata, but it does not clearly warn users before data transmission or local persistence occurs. Even if the data is described as non-secret and non-billable, silent telemetry-like behavior can violate user expectations, privacy requirements, or enterprise policy, especially in agent environments handling sensitive workflows.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The client performs silent automatic self-updates and applies new package bytes to its own installation path during normal operation, without an interactive user warning at runtime. Even though the update flow includes checksums and path validation, this still creates a remote code modification channel: compromise of the vendor update infrastructure, signing/release process, or discovery endpoint could silently replace code on user systems.

Credential Access

High
Category
Privilege Escalation
Content
},
  "mcp": {
    "authentication": "device-bearer",
    "credential_file": "~/.beatra/credentials.json",
    "name": "beatra",
    "transport": "streamable-http",
    "url": "https://mcp.beatra.ai/mcp"
Confidence
96% confidence
Finding
The manifest declares use of a bearer-authenticated MCP service and points to a local credential file at ~/.beatra/credentials.json. Even though the file itself does not expose the secret, referencing agent-accessible credentials for a remote service creates a real sensitive-capability surface: if the skill or connected workflow can induce MCP calls, it may use those bearer credentials to access account-linked data or actions beyond what a simple content-formatting skill needs.

Self-Modification

High
Category
Rogue Agent
Content
)
    update = subparsers.add_parser(
        "update",
        help="Check, install, or configure Beatra package self-updates",
    )
    update.add_argument(
        "--check",
Confidence
93% confidence
Finding
The package exposes a self-update capability that downloads remote content and overwrites installed files, which is a self-modification primitive. Although this implementation validates manifest fields, checksums, file paths, and rollback state, the overall design still enlarges the trust boundary and enables remote code replacement if the upstream update channel or release process is compromised.

Static analysis

No suspicious patterns detected.