Back to skill

Security audit

xiaohongshu-policy-talking

Security checks for vulnerabilities and agentic risk

Overview

The skill has a real media-generation purpose, but it also uses broad shared account authority and silent executable self-updates that need review before installation.

Install only if you are comfortable giving this package a shared Beatra device credential with broad media, artifact, task, and wallet-related authority. Before using it, consider disabling automatic updates with the documented update command, and treat paid or canceling operations as requiring explicit user approval.

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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:34
Finding
Overprivileged Device Authorization and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:34-37`; `scripts/mcp_client.py:1445-1464`; `scripts/mcp_client.py:1490-1491` **Vulnerability Type**: Excessive authorization scope and missing tool allowlist **Risk Level**: High ### Vulnerable Code ```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" ) ``` ```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}, ) ``` ```python call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin") call.add_argument("tool_name") ``` ### Technical Analysis The authorization flow requests broad permissions including image generation, music generation, wallet spending, artifact access, and task cancellation. Some of these capabilities are unrelated to the declared Xiaohongshu policy talking workflow. The command dispatcher accepts an arbitrary tool name from the command line and forwards it to the remote MCP service using the shared bearer credential. It does not enforce a package-specific allowlist or distinguish read-only operations from paid, destructive, or privilege-sensitive operations. Consent requirements are documented in `SKILL.md`, but ...[truncated 1503 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the broad shared scope with the minimum permissions required by this Skill. 2. Remove unrelated permissions such as `images:generate` and `music:generate` unless a documented workflow requires them. 3. Separate read-only, upload, paid-generation, spending, and cancellation capabilities into independently authorized scopes. 4. Implement a hardcoded local allowlist containing only the required Beatra tools, such as the specifically documented model, social lookup, upload, speech, voice, video, task, and wallet operations. 5. Reject unknown tool names before creating an MCP request. 6. Enforce explicit confirmation for paid or destructive operations in executable code rather than relying exclusively on natural-language instructions. 7. Consider using a separate package-specific credential instead of a shared full-scope device token. 8. Add tests proving that unrelated generation tools, cancellation operations, and unknown future tools are rejected locally. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding
Silent Remote Code Replacement Without Independent Publisher Authentication<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:31-32`, `scripts/mcp_client.py:272-307`, `scripts/mcp_client.py:969-1018`, `scripts/mcp_client.py:1534`; `SKILL.md:267-284` **Vulnerability Type**: Automatic remote payload retrieval and package code replacement **Risk Level**: High ### Vulnerable Code ```python PACKAGE_DISCOVERY_URL = "https://beatra.ai/skills/xiaohongshu-policy-talking/channels/clawhub/install.json" PACKAGE_CDN_BASE_TEMPLATE = "https://cdn.beatra.ai/agent-packages/xiaohongshu-policy-talking/channels/clawhub/v{version}" ``` ```python def check_update( *, get_bytes: GetBytes = _default_get_bytes, ) -> dict[str, Any]: discovery = _json_object( get_bytes( _discovery_url(), UPDATE_DISCOVERY_TIMEOUT_SECONDS, MAX_UPDATE_DISCOVERY_BYTES, ), "Beatra update discovery", ) current = _semver(PACKAGE_VERSION) available = _semver(discovery.get("version")) _release_urls(discovery) if available < current: raise RuntimeError("Beatra update discovery attempted a version downgrade") return { "current_version": PACKAGE_VERSION, "available_version": discovery["version"], "update_available": available > current, "discovery": discovery, } ``` ```python manifest_content = get_bytes( manifest_url, UPDATE_DOWNLOAD_TIMEOUT_SECONDS, MAX_UPDATE_MANIFEST_BYTES, ) if _sha256(manifest_content) != discovery["manifest_sha256"]: raise RuntimeError("Beatra update manifest checksum does not match discovery") ``` ```python else: maybe_auto_update() ``` The declared runtime behavior also states: ```text The bundled client silently checks for a newer release at most once every 24 hours per installation. When a newer version is available, it installs automatically without separate confirmation. ``` ### Technical Analysis The updater automatically retrieves and installs a higher package versio ...[truncated 2285 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default and require explicit user approval before replacing executable files. 2. Sign each release manifest with an offline publisher key. 3. Embed or securely pin the corresponding verification public key in the reviewed client. 4. Verify the signature before trusting version numbers, file hashes, archive hashes, or replacement instructions. 5. Consider transparency-log verification or reproducible release metadata to make unauthorized publishing detectable. 6. Preserve the existing checksum, archive validation, path validation, ownership tracking, rollback, and downgrade prevention as defense-in-depth controls. 7. Separate update checking from update installation so ordinary MCP calls never silently change executable code. 8. Clearly report the current version, target version, changed executable files, and signature identity before installation. ]]>

other

Note
Location
scripts/authorize.py:348
Finding
Hostname Collection and Transmission Exceed Documented Registration Telemetry<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:348-368`, `scripts/authorize.py:472-486`; `references/installation-registration.md:3-5` **Vulnerability Type**: Undisclosed host-identifying telemetry **Risk Level**: Low ### Vulnerable Code ```python def device_display_name() -> str | None: """A hostname the user will recognise in the console device list.""" try: name = socket.gethostname().strip() except OSError: return None if not name or not name.isprintable(): return None return name[:120] ``` ```python form: dict[str, str] = { "client_id": CLIENT_ID, "resource": MCP_URL, "scope": SCOPE, "platform": host_platform, "client_name": PACKAGE_DISPLAY_NAME, "external_installation_ref": external_reference, "package_version": PACKAGE_VERSION, "package_slug": PACKAGE_SLUG, } if device_name: form["device_name"] = device_name status, created = post_form(DEVICE_AUTHORIZATION_URL, form) ``` The registration documentation describes the transmitted registration data as follows: ```text Registration records the package slug, version, platform, and stable external installation reference. ``` ### Technical Analysis The authorization helper reads the system hostname and sends it to Beatra as `device_name`. Reading a single hostname is not broad or systematic environment reconnaissance, and the value is used to identify the device in the service console. Nevertheless, the hostname is not required to complete OAuth device authorization, and it can contain sensitive organizational or personal naming information. The installation registration documentation lists the package slug, version, platform, and stable installation reference, but does not list the hostname as transmitted telemetry. The code also detects the Agent platform from environment variables. Platform telemetry is documented; the hostname transmission is not equivalently disclosed in the reviewed referen ...[truncated 889 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not collect or transmit the hostname by default. 2. Generate a neutral local display label that does not expose system naming information. 3. If a recognizable hostname is desired, make collection opt-in and display the exact value before transmission. 4. Update the privacy and installation documentation to enumerate every transmitted field, including `device_name`. 5. Allow users to provide an explicit non-sensitive device label. 6. Apply a stricter character policy if hostname transmission remains supported, and avoid persisting it when it is not necessary. 7. Document the retention, purpose, and deletion behavior for the hostname and stable installation identifier. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (22)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill exercises sensitive capabilities including file access, shell execution, network access, environment access, and file writes, yet it declares no permissions. That creates a transparency and least-privilege problem: users and hosts cannot accurately assess or constrain what the skill may do, especially since it invokes a bundled client, reads local files, uploads assets, and performs updates.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The advertised purpose is a narrowly scoped media-generation workflow, but the skill also performs credential handling, local state storage, arbitrary remote tool invocation through the bundled client, file uploads, telemetry/registration, uninstall/revocation behavior, and self-update logic. This mismatch materially increases attack surface and can mislead operators about data flows, persistence, and code that may run on the host.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
This documentation introduces a bundled client that silently checks for and installs software updates, which is unrelated to the skill's stated purpose of generating Xiaohongshu policy talking clips. Even though the text describes integrity checks and rollback protections, embedding self-updating behavior in an unrelated skill expands the trust boundary and can enable unauthorized code changes if the update mechanism or distribution endpoints are ever compromised.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
A silent automatic updater that checks, downloads, and installs changes by default is a system-modifying capability with clear abuse potential, and it is not justified by the skill's business purpose. In this skill context, the mismatch makes the behavior more suspicious because users would expect media-generation features, not autonomous software modification.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The OAuth scope set is far broader than the stated purpose of creating policy talking clips from existing stills and text. Requesting unrelated capabilities such as wallet spending, music generation, voice management, task cancellation, and broad artifact access violates least privilege and means a compromised or abused skill could act far beyond user expectations.

Context-Inappropriate Capability

Critical
Confidence
99% confidence
Finding
The scope list includes multiple capabilities unrelated to a narrow talking-clip workflow, including images, videos, music, voices read/write, task management, and broad artifact access. In the context of this skill, that creates unnecessary attack surface and allows abuse of the user's account for unrelated operations.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The scope list includes multiple capabilities unrelated to a narrow talking-clip workflow, including images, videos, music, voices read/write, task management, and broad artifact access. In the context of this skill, that creates unnecessary attack surface and allows abuse of the user's account for unrelated operations.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
This client includes a full self-update, installation-state, and package-management subsystem that is unrelated to the stated purpose of generating policy talking clips. Bundling broad package-management capabilities into a content-generation skill materially expands the trust boundary: the code can download, validate, and replace local package files, creating a powerful code-modification path if the update channel or surrounding supply chain is compromised.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The code records local skill inventory and sends installation registration telemetry that is not necessary for turning policy notes into talking clips. Even if framed as telemetry, it collects and persists installation metadata and transmits package/platform identifiers, increasing privacy exposure and normalizing hidden side behaviors unrelated to user-requested media generation.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Host-platform detection and environment fingerprinting are not justified by the declared functionality of a policy talking studio. Collecting execution-environment identifiers broadens observability of the user environment and can support tracking, segmentation, or platform-specific behavior that the user did not request.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The CLI supports generic MCP tool listing and arbitrary tool invocation from stdin rather than only narrowly scoped talking-clip actions. That makes this client a general remote capability broker: anyone able to run it can call any accessible MCP tool with the stored bearer credential, far exceeding the skill's stated purpose and increasing the blast radius of misuse or compromise.

Intent-Code Divergence

Low
Confidence
84% confidence
Finding
The registration path is described as harmless best-effort support, but it still performs remote installation tracking unrelated to the immediate media task. The danger is primarily transparency and scope creep: users invoking a creative action also trigger background telemetry and package registration without direct need.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
This uninstall script manages shared Beatra device credentials and revokes them over the network, which is materially unrelated to the declared Xiaohongshu policy-clip generation purpose. Even if intended as platform lifecycle management, it introduces privileged account/control-plane behavior into a content-production skill, expanding the attack surface and creating a capability mismatch that could be abused to disrupt other installed skills on the same device.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The code performs OAuth device-token revocation via an outbound network request during uninstall. In isolation that can be legitimate, but in this skill context it is unjustified and risky because a media-generation skill should not need token-management capabilities; if triggered unexpectedly, it could sever platform access or create a denial-of-service condition for the user’s other tooling.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that the bundled client silently checks for and automatically installs newer releases without separate confirmation. Even with signature verification, this is integrity-affecting behavior that changes executable code after initial trust, and the skill description does not prominently warn users up front, reducing informed consent and complicating change control.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation states that update checks are silent and enabled by default, and that higher versions are installed automatically without separate confirmation. That creates a transparency and consent problem for users because normal use of the client can trigger system modifications without an adequately prominent warning, increasing the chance of unintended changes or abuse if the updater is subverted.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The documentation states that the bundled client automatically performs an installation registration call and writes a local cache, but it does not clearly warn users up front that metadata is transmitted automatically. Even if the data is described as non-billable and non-secret, automatic outbound registration can be telemetry-like behavior that affects privacy, compliance, or user trust when done without explicit notice or consent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
maybe_auto_update() silently checks for and applies updates during normal command execution, modifying installation files without contemporaneous user confirmation. Although the implementation includes integrity checks, silent code replacement in a content-generation skill is risky because it changes executable behavior outside the user's immediate awareness and creates a supply-chain attack surface.

Missing User Warnings

Low
Confidence
88% confidence
Finding
Installation registration telemetry transmits package and platform metadata without user-facing disclosure at the point of use. While the data appears limited, hidden outbound metadata collection is still a security/privacy concern, especially in a skill whose advertised purpose is only clip production.

Credential Access

High
Category
Privilege Escalation
Content
#: these and then removes the directory only if it is empty — the script
#: never recursively deletes a directory it does not fully understand.
_STATE_FILES = (
    "credentials.json",
    "installation.json",
    "host.json",
    "skills.json",
Confidence
88% confidence
Finding
The script explicitly targets credentials.json as part of shared state handling, indicating access to authentication material. Access to shared credential files is highly sensitive; in this context, a skill unrelated to authentication should not be able to read or influence shared device credentials, because compromise or misuse can affect all skills using the shared connection.

Credential Access

High
Category
Privilege Escalation
Content
def _device_token(state_dir: Path) -> str | None:
    path = state_dir / "credentials.json"
    try:
        value = json.loads(path.read_text(encoding="utf-8"))
    except (OSError, ValueError):
Confidence
95% confidence
Finding
The _device_token function reads access_token from ~/.beatra/credentials.json so it can be sent to the revocation endpoint. Direct extraction of bearer tokens by a skill is dangerous because it grants the skill visibility into reusable authentication secrets; if modified or repurposed, this pattern could enable credential theft or unauthorized API actions beyond uninstall.

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
96% confidence
Finding
The skill exposes self-modification through an update command and related update machinery, allowing the package to replace its own installed files. Even with signature-by-hash style validation against discovery metadata, self-modifying behavior is dangerous in a narrowly scoped skill because it introduces a persistent code-change channel and substantially raises the impact of any supply-chain or backend compromise.

Static analysis

No suspicious patterns detected.