Back to skill

Security audit

AI Headshot Studio

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a headshot-generation service, but it asks for broad reusable Beatra account powers and can silently replace its own code.

Review this before installing if you only expect a narrow headshot tool. It uploads selected images and performs paid Beatra generation after confirmation, but the same reusable Beatra token covers unrelated media capabilities and wallet spending, and the bundled client can call arbitrary Beatra MCP tools. Consider disabling automatic updates with the documented command and only install if you trust Beatra's service, update channel, and shared credential design.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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:33
Finding

Overly Broad Authorization Scope and Unrestricted MCP Tool Dispatch

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:33-36; scripts/mcp_client.py:1463-1482
Vulnerability Type: Excessive privileges and unrestricted remote tool selection
Risk Level: High

Vulnerable Code

scripts/authorize.py:33-36:

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 declared functionality is professional headshot generation and editing. It legitimately requires image generation, artifact upload, task tracking, and potentially spending authorization. However, the requested bearer-token scope also grants video generation, music generation, speech generation, voice creation and modification, and general wallet spending.

The bundled client compounds this excessive scope by accepting an arbitrary MCP tool name from the command line. It does not enforce an allowlist limited to the image and task operations documented by the Skill. Consequently, possession of or access to the client and shared ...[truncated 2037 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the shared full-scope token with a package-specific, least-privilege credential.
  2. Remove unrelated permissions, including:
    • videos:generate
    • music:generate
    • speech:generate
    • voices:read
    • voices:write
  3. Narrow wallet authorization to package-specific image operations where supported, rather than granting general spending capability.
  4. Add a local allowlist in _run_command, permitting only the tools required by this Skill, such as the documented image transform/edit, asset upload, model query, billing, and task-management operations.
  5. Reject unknown tool names before creating a remote session or attaching the bearer token.
  6. Separate administrative operations such as installation registration from paid creative-operation credentials.
  7. Add automated tests verifying that unrelated video, music, speech, and voice tools are denied locally and remotely.
  8. Display the exact requested capabilities during authorization so users can make an informed approval decision.

other

Warning
Location
scripts/authorize.py:342
Finding

Unnecessary Hostname and Agent-Environment Telemetry Collection

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:342-369; scripts/authorize.py:446-464
Vulnerability Type: Environment reconnaissance and persistent device correlation
Risk Level: Medium

Vulnerable Code

scripts/authorize.py:342-369:

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]

scripts/authorize.py:446-464:

python
external_reference = _installation_reference(state_dir)
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:
    
...[truncated 3011 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove automatic hostname collection from the authorization flow.
  2. Use a generic user-facing device label by default, such as AI Headshot Studio, without incorporating local system identifiers.
  3. Make device naming optional and require explicit user input or consent before transmitting a hostname-derived value.
  4. Default platform reporting to unknown unless platform information is technically required for compatibility.
  5. If telemetry is retained, make it opt-in and clearly disclose the exact fields, purpose, retention period, and deletion controls.
  6. Avoid using a long-lived installation identifier for analytics where a short-lived or package-scoped pseudonymous identifier is sufficient.
  7. Keep telemetry logically separated from authentication so authorization succeeds when optional metadata is omitted.
  8. Add tests confirming that authentication and image generation work without device_name, platform detection, or a telemetry identifier.
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 (37)

Context-Inappropriate Capability

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The requested permissions include audio, voice, and video generation plus voice read/write, none of which are aligned with a professional headshot tool. Unneeded creative-media scopes substantially increase abuse potential, especially because the token is reusable and appears intended to be shared across skills in ~/.beatra.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises photo transformation but also includes uninstall logic that accesses shared state under ~/.beatra, revokes credentials remotely, and modifies local installation records. Even if these are legitimate lifecycle operations, bundling them into a headshot skill without clear separation creates deceptive behavior and increases the risk of users authorizing filesystem and account actions they did not expect from an image tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises photo transformation but also includes uninstall logic that accesses shared state under ~/.beatra, revokes credentials remotely, and modifies local installation records. Even if these are legitimate lifecycle operations, bundling them into a headshot skill without clear separation creates deceptive behavior and increases the risk of users authorizing filesystem and account actions they did not expect from an image tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill advertises photo transformation but also includes uninstall logic that accesses shared state under ~/.beatra, revokes credentials remotely, and modifies local installation records. Even if these are legitimate lifecycle operations, bundling them into a headshot skill without clear separation creates deceptive behavior and increases the risk of users authorizing filesystem and account actions they did not expect from an image tool.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 62)May include surrounding context.

md
Use only this Skill's bundled `scripts/mcp_client.py` for every remote MCP

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 166)May include surrounding context.

md
Use only this Skill's bundled `scripts/mcp_client.py` for every remote MCP

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 167)May include surrounding context.

md
Use only this Skill's bundled `scripts/mcp_client.py` for every remote MCP

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 168)May include surrounding context.

md
Use only this Skill's bundled `scripts/mcp_client.py` for every remote MCP

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 71)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/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
99% confidence
Finding

The OAuth scope string requests far more capability than a headshot-generation skill needs, including videos, music, speech, voice management, task control, and wallet spending. Excessive permissions violate least privilege and create a materially larger blast radius if the credential is abused, leaked, or reused by other code sharing the same Beatra credential store.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The requested permissions include audio, voice, and video generation plus voice read/write, none of which are aligned with a professional headshot tool. Unneeded creative-media scopes substantially increase abuse potential, especially because the token is reusable and appears intended to be shared across skills in ~/.beatra.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The client embeds a full self-update channel that can download archives from remote infrastructure and replace installed package files. Although it performs integrity checks, this is still a code-loading and self-modifying mechanism unrelated to the advertised headshot functionality, so compromise of the vendor update pipeline or signing/discovery infrastructure would yield remote code execution in the agent environment.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The CLI exposes self-update behavior as a first-class capability, enabling the package to replace its own installed code. Even if implemented carefully, self-modification is high risk for an end-user headshot tool because it introduces a supply-chain execution path far outside the declared purpose of the skill and can be abused if the update channel is compromised.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This uninstall script is capable of revoking a shared Beatra device credential and deleting shared state under ~/.beatra, which affects more than this single skill. Although the code tries to preserve the connection unless it can prove no other skills remain, that behavior is still outside the expected scope of a headshot-generation skill and creates a high-impact control point over global authentication state.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

Referencing credentials.json as part of the deletion set shows the skill is designed to manipulate shared credential material. Even though this occurrence alone is declarative rather than exfiltrative, granting a non-authentication skill awareness and control over credential files increases the blast radius of compromise or misuse.

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

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code issues an authenticated POST to a revocation endpoint and later removes shared local state files, including credentials and installation metadata, from ~/.beatra. Even if intended for cleanup, this gives a skill package the ability to disrupt account access and other installed skills, which is dangerous for a component whose advertised purpose is image transformation.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

This function reads ~/.beatra/credentials.json to obtain an access token and uses it to perform revocation. Access to bearer tokens by a skill script is highly sensitive because any code path that can read such tokens could be extended, abused, or replaced to exfiltrate them or perform unauthorized account actions.

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
94% confidence
Finding

The skill exposes broad operational capabilities—environment access, file read/write, network, and shell—without declaring an explicit tool scope or permission boundary. In a skill that handles remote uploads, local state, authentication, and updates, this absence reduces transparency and weakens least-privilege controls, making abuse or accidental overreach harder to detect and prevent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.