Back to skill

Security audit

tiktok-shop-product-video-maker

Security checks for vulnerabilities and agentic risk

Overview

This skill is in Review because it does more than write video plans: it uses a broad shared Beatra token, can call arbitrary remote tools, can upload local files, and silently replaces its own package files by default.

Install only if you trust Beatra with a persistent shared device token that may carry paid-generation and wallet authority, and with a client that can call broad remote tools and update itself. Disable automatic updates if you want reviewed package files to stay fixed, and avoid using the upload or generic call commands with sensitive local files.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:34
Finding

Excessive OAuth scopes combined with unrestricted MCP tool invocation

Content
View full analysis
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 declared Skill functionality is limited to producing a non-billable product-video plan. Its documentation explicitly states that the package does not render media and creates no paid generation task. Despite that limited purpose, authorization requests permissions for: - Wallet spending - Image, video, music, speech, and voice generation - Artifact creation - Voice modification - Task cancellation - Task and artifact access - General MCP tool access The bundled client then exposes a generic `call` command that accepts any tool name from the command line and forwards arbitrary JSON arguments. Ther ...[truncated 1529 chars]
Remediation
View remediation
` interface with a hardcoded allowlist of approved tool names. 5. Validate each tool's argument schema locally before transmission. 6. Require explicit user confirmation for any operation that can spend funds, create billable tasks, modify remote state, or cancel work. 7. Enforce equivalent restrictions server-side so a modified local client cannot bypass the package's capability boundary. 8. Avoid sharing a highly privileged credential across unrelated Skills. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding

Silent remote package-code replacement is enabled by default

Content
View full analysis
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, ) discovery = checked["discovery"] manifest, new_files = download_update(discovery, get_bytes=get_bytes) _apply_update( install_root=resolved_root, ...[truncated 2882 chars]
Remediation
View remediation

other

Note
Location
scripts/authorize.py:363
Finding

Hostname and Agent-platform telemetry exceed the minimum requirements

Content
View full analysis
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 if device_name: form["device_name"] = device_name ``` Every business tool call also receives source attribution: ```python if method == "tools/call": arguments = params.get("arguments") if isinstance(arguments, dict): arguments.setdefault("source_package_slug", PACKAGE_SLUG) arguments.setdefault("source_platform", host_platform()) ``` ### Technical Analysis The authorization process retrieves the machine hostname and sends it to Beatra as `device_name`. The client also detects the Agent runtime from process-environment signatures and attaches that platform identity and package slug to remote tool calls. This is limited environment reconnaissance rather than broad host discovery: the code does not enumerate interfaces, obtain IP addresses, inspect cloud metadata, or search for unrelated credentials. Nevertheless, the hostname and Agent runtime are not required to generate a TikTok Shop product-video plan. Their collection therefore exceeds the minimum information necessary for the declared creative-writing functionality. The package documentation discloses platform and package source attribution, but the hostname transmission is less clearly surfaced in the main Skill description. ### Attack Path 1. The user runs the authorization helper. 2. `socket.gethostname()` retrieves the local host identifier. 3. The hostname is added to the device-authorization form. 4. The package also ...[truncated 739 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/mcp_client.py:1419
Finding

Generic local-file upload capability is outside the declared planning scope

Content
View full analysis
dict[str, str]: if re.fullmatch(r"[a-z0-9][a-z0-9.+-]*/[a-z0-9][a-z0-9.+-]*", mime_type) is None: raise RuntimeError("Local upload MIME type is invalid") filename, content = _read_local_upload(path) resolved_state_dir = state_dir or Path.home() / ".beatra" session = _session_with_registration(state_dir=resolved_state_dir, post_json=post_json) result = session.request( 2, "tools/call", { "name": "beatra.assets.upload", "arguments": { "filename": filename, "mime_type": mime_type, "size_bytes": len(content), }, }, ) if failure := _tool_failure_message(result): raise RuntimeError(f"Beatra rejected the upload grant request: {failure}") return _complete_upload( result, mime_type=mime_type, content=content, put_bytes=put_bytes, ) ``` The upload parser accepts a general local path: ```python local_upload = subparsers.add_parser( "upload", help="Upload one local regular file and print its artifact reference", ) local_upload.add_argument("path", type=Path) ``` The server-provided destination is restricted to HTTPS, but not to a fixed hostname: ```python parsed = urllib.parse.urlsplit(url) if ( parsed.scheme != "https" or not parsed.hostname or parsed.username is not None or parsed.password is not None or parsed.fragment ): raise RuntimeError("Beatra upload instructio ...[truncated 1906 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to generate marketing assets, yet it also includes uninstall/disconnect behavior that reads and modifies local state and revokes authorization over the network. Such unrelated lifecycle-management operations increase the attack surface and can affect a host environment in ways a user would not reasonably expect from a video-planning tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to generate marketing assets, yet it also includes uninstall/disconnect behavior that reads and modifies local state and revokes authorization over the network. Such unrelated lifecycle-management operations increase the attack surface and can affect a host environment in ways a user would not reasonably expect from a video-planning tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to generate marketing assets, yet it also includes uninstall/disconnect behavior that reads and modifies local state and revokes authorization over the network. Such unrelated lifecycle-management operations increase the attack surface and can affect a host environment in ways a user would not reasonably expect from a video-planning tool.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Automatic downloading and installation is inappropriate for a product-video planning skill because it grants the package the ability to change executable behavior without a fresh trust decision by the user or reviewer. This elevates the impact of any compromise of the update path and is especially dangerous given the skill's mismatch with its stated non-operational purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · manifest.json (reported line 60)May include surrounding context.

json
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/mcp-connection.md (reported line 10)May include surrounding context.

text

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/authorize.py (reported line 207)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/authorize.py (reported line 514)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/mcp_client.py (reported line 1025)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The requested OAuth scope set is far broader than the advertised function of generating TikTok Shop product-video plans. In addition to artifacts access, it requests image/video/music/speech generation, voice read/write, task control, and wallet:spend, creating unnecessary privilege that could enable unauthorized spending or broader account misuse if the token is abused or the skill is compromised.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The package contains built-in self-update capability that downloads remote artifacts and replaces local files, which is self-modifying behavior. Even with checksum validation, this is high-risk in a skill because compromise or misuse of the update channel would let remote infrastructure alter installed code outside normal review and with little user awareness.

Content

Scanner excerpt · scripts/mcp_client.py (reported line 1503)May include surrounding context.

python
)
    update = subparsers.add_parser(
        "update",
        help="Check, install, or configure Beatra package self-updates",
    )
    update.add_argument(
        "--check",

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

Referencing credentials.json as part of removable shared state indicates the skill is designed to handle credential-bearing files. For a video-maker skill, access to credential storage is unnecessary for core functionality and creates a high-risk primitive: if modified or abused, the package could exfiltrate, destroy, or misuse authentication material.

Content

Scanner excerpt · scripts/uninstall.py (reported line 40)May include surrounding context.

python
#: 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",

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The _device_token function reads an access token from ~/.beatra/credentials.json in order to call a remote revoke endpoint. Reading bearer tokens inside a skill package is dangerous because the same access path could be repurposed for token theft or unauthorized API actions, and it is unrelated to the advertised product-video planning capability.

Content

Scanner excerpt · scripts/uninstall.py (reported line 109)May include surrounding context.

python
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):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill declares itself as a content-planning package, yet the documentation references a bundled client with network, filesystem, shell, and update capabilities without any explicit tool-scope declaration. This violates least-privilege expectations and makes it harder for users or reviewers to understand what the skill can actually access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states it is non-billable planning only, yet the documentation also describes external service registration, connector restrictions, and bundled-client use. That inconsistency is a warning sign because it obscures that the skill interacts with external systems and may establish persistent installation state despite appearing to be a simple planning helper.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation introduces self-updating package behavior that is unrelated to generating product-video plans. Even if update sources are described as verified, self-update materially changes the installed code after review, weakening trust boundaries and creating a supply-chain risk in a low-need context.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · manifest.json (reported line 9)May include surrounding context.

json
"icon": "https://beatra.ai/textures/icons/tiktok-shop-product-video-maker-0.1.1.png",
  "localized": {
    "en": {
      "description": "Create TikTok Shop product-video plans from product facts, photos, selling points, and English or Japanese audience context. This AI product video maker produces hooks, a ready-to-film script, shot beats, subtitle cues, localized titles, hashtags, and a product-page-safe CTA for product showcases, demonstrations, unboxings, reviews, and creator-led shopping videos.",
      "display_name": "TikTok Shop Product Video Maker",
      "summary": "Turn product facts, photos, and an English or Japanese audience brief into a TikTok Shop product-video script, shot plan, captions, and localized post copy.",
      "tags": [

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The English localized description and summary explicitly constrain the skill to "English or Japanese audience context/brief." This is a natural-language locale restriction presented as part of the skill behavior, but the manifest does not indicate that users can choose other languages or that the limitation is justified by a region-specific compliance need.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The Japanese description and summary state that outputs are generated from an English or Japanese target audience. This enforces a specific language/locale scope in natural language, and the manifest does not clearly frame it as an optional user choice or justified regional limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The Chinese text says the skill creates plans from product information and "English or Japanese audience needs," which is a locale constraint. Because the manifest does not state this as an opt-in choice or provide a documented justification, it fits the policy concern for forced language/locale behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file states that updates are enabled by default, performed silently, and installed automatically without separate confirmation. Because the behavior modifies installed package files on the user's system, the description should include a more explicit warning that local files will be replaced automatically unless the user opts out.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The code identifies the host agent platform from environment variables and captures the local hostname for transmission/storage during authorization. For a product-video planning skill, this creates unnecessary device and environment fingerprinting that increases privacy risk and can aid tracking or profiling across installations without being clearly required for core functionality.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill writes a local inventory of installed skills including slug, platform, and resolved installation path into ~/.beatra/skills.json, which is unrelated to creating video plans. This creates unnecessary local surveillance of other installed packages and filesystem layout, expanding privacy exposure and potentially revealing sensitive path information to any process or future component that can read the shared state directory.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file embeds self-update, remote package discovery, and installation-channel logic in a skill advertised as a TikTok product-video planner. Even though parts of the updater are hardened, this materially expands the trust boundary: code execution behavior now depends on remote infrastructure unrelated to the narrowly described business function, increasing supply-chain and unexpected-network-activity risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

maybe_auto_update() silently performs network fetches and local package replacement during ordinary command execution, with failures suppressed and no runtime disclosure. In a skill context, silent self-modification is especially dangerous because it changes executable code after installation, increases supply-chain risk, and can defeat a user's expectation that a reviewed skill remains stable.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.