Back to skill

Security audit

Field Check Pack

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent image-generation purpose, but it also grants broad Beatra account authority and silently self-updates local executable files by default.

Install only if you are comfortable giving this package a shared Beatra device credential with broad media and wallet-related authority, and consider disabling automatic updates immediately with `python3 scripts/mcp_client.py update --auto off`. Treat any generated image request as billable work and avoid uploading sensitive local files as references.

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)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding

Silent Self-Update Allows Post-Audit Replacement of Executable Skill Files

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:969-1018; supporting behavior is documented in SKILL.md:167-185 and references/automatic-updates-and-safety.md:3-19
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Vulnerable Code

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,
            )
            discovery = checked["discovery"]
 
...[truncated 3447 chars]
Remediation
View remediation

Remediation Suggestions

  1. Disable automatic updates by default and require an explicit user action before downloading or installing each new version.
  2. Display the target version, release source, changed executable files, and security implications before installation.
  3. Sign release manifests with an offline publisher key and pin the corresponding public key in the audited client.
  4. Verify the signature before trusting any version, URL, archive hash, or file hash from discovery metadata.
  5. Consider threshold signing or transparency-log verification for release artifacts.
  6. Separate executable updates from non-executable resource updates. Never silently replace Python scripts or agent instruction files.
  7. Preserve the existing path, size, checksum, ownership, rollback, and redirect protections as defense-in-depth.
  8. Ensure update failures and successful updates are visibly logged without exposing credentials or user content.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:34
Finding

Field-Check Image Skill Requests Broad Unrelated Scopes and Permits Arbitrary MCP Tool Names

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:34-38 and scripts/mcp_client.py:1463-1482
Vulnerability Type: Excessive authorization and missing local tool allowlist
Risk Level: High

Vulnerable Code

The authorization request obtains capabilities unrelated to field-check image production:

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"
)

The command dispatcher accepts any caller-provided tool name and forwards it to the authenticated MCP endpoint:

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 declared Skill functionality is producing field-check still images. Its documented workflow requires a substantially narrower set of operations:

  • model-card lookup for image generation and editing;
  • image generation and image editing;
  • optional artifact upload;
  • task reads and user-requested task cancellation;
  • wallet balance or ledger reads;
  • installation registration.

The authorization scope additionally includes video generation, music generation, speech generation, voi ...[truncated 2009 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the full-scope shared credential with a package-specific, least-privilege credential.
  2. Request only the scopes required by this Skill, such as image generation/editing, necessary artifact access, model reads, task reads, explicitly requested cancellation, and read-only wallet access.
  3. Remove video, music, speech, and voice-write permissions from this package.
  4. Avoid a generalized wallet-spend permission when billing can be authorized at the specific image-generation operation.
  5. Add a strict local allowlist for tool names, for example:
    • beatra.models.list
    • beatra.images.generate
    • beatra.images.edit
    • beatra.assets.upload
    • beatra.tasks.get
    • beatra.tasks.list
    • beatra.tasks.cancel
    • beatra.wallet.get
    • beatra.wallet.ledger
    • beatra.installations.register
  6. Reject all unknown tools before creating an authenticated session.
  7. Separate read-only and billable operations into distinct scopes or credentials where supported.
  8. Require explicit user approval immediately before any billable or state-changing call.

other

Warning
Location
scripts/authorize.py:343
Finding

Authorization Collects and Transmits Hostname and Agent-Environment Telemetry Beyond Core Image Functionality

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:343-373 and scripts/authorize.py:461-473; related registration behavior appears in scripts/mcp_client.py:1139-1166 and scripts/mcp_client.py:1354-1398
Vulnerability Type: Environment reconnaissance and telemetry collection
Risk Level: Medium

Vulnerable Code

The authorization helper detects the agent environment and obtains the local hostname:

python
def detect_host_platform(explicit: str | None = None) -> str:
    """The agent environment this process runs inside (docs/device-model.md).

    Order: explicit agent self-report > environment signatures > unknown.
    Detection reads the process environment only — nothing else runs,
    nothing reaches the network.
    """
    if explicit:
        candidate = explicit.strip().lower().replace(" ", "-")
        if _PLATFORM_VALUE.fullmatch(candidate):
            return candidate
    env = os.environ
    if env.get("CLAUDECODE") == "1" or "CLAUDE_CODE_ENTRYPOINT" in env:
        return "claude-code"
    if any(key.startswith("CODEX_") for key in env):
        return "codex"
    ai_agent = env.get("AI_AGENT", "").lower()
    matched = re.match(r"([a-z0-9-]+)_", ai_agent)
    if matched and _PLATFORM_VALUE.fullmatch(matched.group(1)):
        return matched.group(1)
    return "unknown"


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]

The resulting values are added to the device-authorization request:

python
form: dict[str, str] = {
    "client_id": CLIENT_ID,
    "resource": MCP_URL,
    "scope": SCOPE,
    "platform": host_platform,
    "client_name": PACKAGE_DISPLAY_NAME,
    "externa
...[truncated 2478 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not collect or transmit the hostname by default.
  2. Use a generic user-selected device label or a random local identifier instead of socket.gethostname().
  3. Obtain explicit, informed opt-in before collecting agent-platform or device-name telemetry.
  4. Clearly disclose each transmitted field, its purpose, retention period, and whether it is visible to other account users.
  5. Default platform to unknown unless the user explicitly elects to provide it.
  6. Keep source attribution separate from business-operation arguments and ensure telemetry cannot affect authorization or billing.
  7. Provide a configuration setting that permanently disables registration and source-attribution telemetry.
  8. Minimize retention and avoid correlating telemetry with prompts, uploaded content, or billing records unless strictly required and disclosed.
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 (38)

Context-Inappropriate Capability

Critical
Category
Not specified by scanner
Confidence
100% confidence
Finding

The requested OAuth scope includes capabilities unrelated to the skill's purpose, including wallet spending, task cancellation, artifacts read/write, and music/speech/video/voice operations. Overbroad scopes dramatically increase blast radius: if the token is misused, compromised, or the backend behaves unexpectedly, an attacker could spend funds, manipulate tasks, or access unrelated user content far beyond field-check generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill presented as a graphics-generation workflow also references uninstall/removal behavior, token revocation, reading credential and inventory files, and deleting local state. That is dangerous because destructive or account-affecting operations can be hidden behind an unrelated description, making accidental invocation or overtrust more likely.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill presented as a graphics-generation workflow also references uninstall/removal behavior, token revocation, reading credential and inventory files, and deleting local state. That is dangerous because destructive or account-affecting operations can be hidden behind an unrelated description, making accidental invocation or overtrust more likely.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill presented as a graphics-generation workflow also references uninstall/removal behavior, token revocation, reading credential and inventory files, and deleting local state. That is dangerous because destructive or account-affecting operations can be hidden behind an unrelated description, making accidental invocation or overtrust more likely.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This documentation describes an automatic self-updating mechanism that is unrelated to the stated purpose of a field-check-set content generation skill. Even though it is documentation rather than executable code, bundling self-update behavior into an unrelated skill increases supply-chain and trust-boundary risk, especially because users would not reasonably expect local package modification from this skill context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file states that the client silently checks for and automatically installs newer releases by default, without separate confirmation. Silent self-update and file replacement are dangerous in an unrelated skill because they enable unexpected code changes on the user's system, expand the blast radius of any upstream compromise, and undermine informed user consent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file directs the host to install and authorize a separate Beatra ecosystem, store a long-lived device token, and connect to an external MCP endpoint that is unrelated to the declared purpose of the field-check-set skill. That mismatch is a strong supply-chain red flag because a seemingly simple inspection-content skill should not require persistent third-party authentication and remote tool access, creating an opportunity for unintended data access or covert capability expansion.

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 53)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/installation-and-auth.md (reported line 14)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 · references/installation-and-auth.md (reported line 21)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 · references/installation-and-auth.md (reported line 49)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 · 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/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

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/uninstall.py (reported line 40)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/uninstall.py (reported line 109)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
99% confidence
Finding

The script initiates an OAuth device authorization flow and acquires a reusable account credential for a skill whose stated purpose is generating field inspection still sets. That account-binding behavior is materially broader than the declared functionality and creates an unnecessary trust boundary: installing a simple content skill should not require long-lived account authorization infrastructure unless clearly justified.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The script persists a bearer access token in plaintext JSON on disk, creating a high-value local secret whose compromise would grant all requested account scopes. In the context of this skill, that risk is amplified because the token is already overprivileged relative to the declared purpose, so theft of the file could enable broad account actions.

Content

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

python
scope = _required_string(polled, "scope")
            if set(scope.split()) != set(SCOPE.split()):
                raise RuntimeError("Beatra authorization returned an unsupported scope")
            credential_path = state_dir / "credentials.json"
            _atomic_json(
                credential_path,
                {

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file's behavior is substantially broader than the declared skill purpose: instead of only generating inspection-check-set outputs, it implements a credential-backed remote client with command execution, telemetry, uploads, and package update logic. This mismatch is dangerous because users and reviewers may grant trust based on the manifest while hidden capabilities enable data transmission and code replacement unrelated to the advertised function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The client can read an arbitrary local file path and upload its contents to a remote asset service after obtaining upload instructions. In the context of a skill advertised as transforming check items into still sets, this is over-privileged functionality that could be used to exfiltrate sensitive local data if exposed through the agent or invoked unexpectedly.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code downloads manifests and archives from remote infrastructure and then rewrites local installation files. Even with checksum validation, this gives the package a built-in self-modification channel that can change behavior after installation, increasing supply-chain and trust-boundary risk well beyond the stated inspection-graphics purpose.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The exposed update command explicitly supports self-update, and elsewhere in the file that feature downloads remote package content and replaces local files. Self-modifying behavior is especially risky in a skill whose declared function does not justify code-replacement capability, because it can materially alter trusted behavior after review or installation.

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",

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes shell commands, performs network operations, and appears to read/write local state, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an over-privileged execution surface where a host may permit more capability than users would reasonably expect from a simple image-pack skill, increasing the risk of unintended file, environment, or network access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill includes a self-updating package mechanism unrelated to the user-facing task of generating field-check stills. Any self-update capability expands the trust boundary from the current package to future remote content; if abused or compromised, it can introduce new code and behavior without the user evaluating a new skill package.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that it silently checks for and automatically installs newer releases without separate confirmation. Even with verification claims, silent auto-installation is risky because users invoking a content skill may not realize they are consenting to code changes on the local system, and a future update could widen capabilities or alter behavior unexpectedly.

Content

No source excerpt is available for this finding.