Back to skill

Security audit

Figma To Static 2.0.5

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly aimed at Figma-to-HTML conversion, but it also handles local Claude/Figma authentication, global tool installation, stored credentials, and public preview hosting in ways users should review carefully before installing.

Install only if you are comfortable letting the skill configure Claude/Figma MCP access, handle short-lived OAuth artifacts, optionally read Claude-stored Figma credentials, and modify user-level CLI/MCP setup. Prefer explicit FIGMA_MCP_TOKEN or FIGMA_TOKEN over --allow-claude-credentials, avoid the global setup script unless you have reviewed it, do not paste live auth codes into logged shells, and bind previews to 127.0.0.1 or a sanitized/authenticated preview directory instead of exposing the project root publicly.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (4)

T08 · Insecure Dependencies

Error
Location
scripts/setup_claude_mcp.sh:62
Finding

Unpinned Global Installation of a Third-Party CLI Package

Content
View full analysis
/dev/null 2>&1; then echo "[1/7] Installing Claude CLI..." npm install -g @anthropic-ai/claude-code ``` The same unsafe installation command is recommended in the Skill instructions: ```bash npm install -g @anthropic-ai/claude-code ``` ### Technical Analysis The bootstrap installs the latest available version of `@anthropic-ai/claude-code` globally without pinning an audited version or verifying package integrity. An npm installation may execute package lifecycle scripts using the invoking user's privileges. The `-g` option also modifies the user's or system's global executable environment rather than an isolated project environment. Although the package name is associated with the expected vendor and no malicious package is embedded in this repository, the effective code installed by this command can change after the Skill has been reviewed. This creates a supply-chain trust boundary that is not controlled by the audited project. ### Attack Path 1. An upstream npm account, publishing pipeline, package release, or dependency is compromised. 2. A malicious or unexpectedly unsafe version becomes the latest release of `@anthropic-ai/claude-code`. 3. A user runs the recommended `setup_claude_mcp.sh` bootstrap on a host where `claude` is absent. 4. npm downloads the current release and executes any applicable installation lifecycle code. 5. The package gains the invoking user's privileges and installs a globally accessible executable. 6. Malicious code could access user files, credentials, environment variables, or establish persistence subject to the user's permissions. ### Impact Assessment Successful exploitation provides code e ...[truncated 530 chars]
Remediation
View remediation
``` 2. Verify the expected package integrity, provenance, and publisher before installation. 3. Avoid automatic global installation. Detect the missing CLI and instruct the user to install it only after explicit confirmation. 4. Prefer an isolated project-local installation or a controlled package runner with a pinned version. 5. Record and periodically review the approved version instead of silently accepting the newest release. 6. Where supported, enforce npm provenance/signature verification and use a trusted registry configuration. 7. Clearly disclose that installation may execute third-party lifecycle scripts and modify the global command environment. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/claude_auth_lock.py:179
Finding

OAuth Authorization Artifacts Passed Through Process Arguments

Content
View full analysis
" python3 scripts/claude_auth_lock.py verify-callback --callback-url "" ``` ### Technical Analysis OAuth authorization codes, callback URLs, and state values are authentication artifacts. Passing them as command-line options exposes them outside the intended validation process. Depending on the operating environment, command arguments may be observable through: - Shell history - Process listings such as `ps`, `/proc`, or process telemetry - Terminal session recording - CI/CD command logging - Agent tool-call logs - Debug or audit infrastructure Authorization codes are typically short-lived and may be protected by PKCE or other server-side controls, which can reduce exploitability. Nevertheless, exposing them through argv violates secure secret-handling practice and unnecessarily broadens access to authentication material. ### Attack Path 1. The us ...[truncated 1152 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/claude_auth_lock.py:51
Finding

OAuth Session Lock Persists and Prints Sensitive State Without Explicit Access Controls

Content
View full analysis
None: LOCK_DIR.mkdir(parents=True, exist_ok=True) LOCK_PATH.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n") def print_json(payload: dict) -> None: print(json.dumps(payload, ensure_ascii=False, indent=2)) def cmd_status(_: argparse.Namespace) -> int: lock = load_lock() if not lock: print_json({"status": "NO_ACTIVE_LOCK", "lockPath": str(LOCK_PATH)}) return 0 print_json({"status": "ACTIVE_LOCK", "lockPath": str(LOCK_PATH), "lock": lock}) return 0 ``` The persisted object includes the complete authorization URL and OAuth state: ```python payload = { "phase": args.phase, "sessionId": args.session_id, "pid": args.pid, "authUrl": args.auth_url, "authState": auth_state, "createdAt": now, "updatedAt": now, } save_lock(payload) print_json({"status": "LOCK_ACQUIRED", "lockPath": str(LOCK_PATH), "lock": payload}) ``` The process guard also emits the entire lock: ```python payload = { "status": status, "mode": args.mode, "problems": problems, "recommendedAction": recommended_action, "lockPath": str(LOCK_PATH), "activeLock": lock, "processes": info["all"], "loginCount": info["loginCount"], "claudeCount": info["claudeCount"], } print(json.dumps(payload, ensure_ascii=False, indent=2)) ``` ### Technical Analysis The lock file stores the full OAuth authorization URL, state, session ID, and optional PID. `Path.write_text()` does not explicitly enforce mode `0600`; effective permissions depend on the current umask and pre-existing f ...[truncated 1852 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:492
Finding

Unauthenticated Public Exposure of the Project Working Directory

Content
View full analysis
:PORT/html/` link. - If running behind a firewall, ensure the port is open. ``` ### Technical Analysis `python3 -m http.server` serves the current working directory and enables directory listing by default. The Skill instructs the agent to bind the server to all network interfaces and potentially open the firewall, but it does not require authentication, TLS, source-address restrictions, a sanitized document root, or confirmation that the current directory contains only public files. The prescribed workflow creates or may contain directories such as: - `source/` with raw design exports - `mcp-assets/` or `rest-assets/` with Figma metadata and screenshots - `assets/` with proprietary design files - `compare/` with screenshots and visual-diff output - Project files unrelated to the intended preview A link ending in `/html/` does not constrain the server to that directory. A remote visitor can request `/`, enumerate directory listings, and access any readable file beneath the server's current working directory. ### Attack Path 1. The Skill runs the preview command from the project root on a cloud host. 2. The server listens on `0.0.0.0`, making it reachable through every configured network interface. 3. The firewall or cloud security group is opened as instructed. 4. An attacker discovers the port through ...[truncated 1024 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (47)

Tainted flow: 'req' from os.environ.get (line 59, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/fetch_figma_rest.py (reported line 61)May include surrounding context.

python
attempt += 1
        req = urllib.request.Request(url, headers={"X-Figma-Token": token})
        try:
            with urllib.request.urlopen(req, timeout=timeout) as resp:
                return json.loads(resp.read())
        except urllib.error.HTTPError as e:
            if e.code != 429:

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill directs installation of global CLI tooling, login-flow control, MCP configuration, quota checks, and auth management, all beyond the expected scope of a static page generator. This broad operational behavior can modify the host environment and interact with account state in ways the user may not anticipate from the skill name and description.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill explicitly references a local credential file path (~/.claude/.credentials.json), indicating credential-adjacent access beyond what a user would expect from a design-conversion skill. Accessing local credential stores can expose tokens or account metadata and significantly increases sensitivity if the skill is invoked in a broad-trust environment.

Content

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

md
layered DOM reconstruction (not whole-image paste), visual diff pipeline with region heatmap for
  quality validation, mobile-first responsive layout.
  NOT for: React/Vue/SPA frameworks, server-side rendering, interactive JS-heavy pages.
metadata: {"clawdbot":{"emoji":"🎨","requires":{"bins":["python3"],"env":["FIGMA_MCP_TOKEN","FIGMA_TOKEN"]},"configPaths":["~/.claude/.credentials.json"]}}
---

# Figma → Static HTML/CSS

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 · SKILL.md (reported line 166)May include surrounding context.

text
- **200** → Token valid. Use quota-aware REST mode first:
  - `python3 scripts/fetch_figma_rest.py --file-key FILE_KEY --nodes "NODE1,NODE2" --quota-aware --batch-size 3 --max-retry-after 60`
- **401/403** → Guide user to generate token at Figma → Account Settings → Personal access tokens.
- **429** → Do not tight-retry. Reduce batch size (`--batch-size 1~2`) or switch to `--metadata-only` skeleton flow.

**Priority 3: User-provided assets** (fallback)

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The documentation identifies an exact credential file path and token location inside ~/.claude/.credentials.json, which materially assists credential discovery and use. In an agent skill, that is dangerous because it normalizes harvesting locally stored OAuth tokens for a different toolchain rather than requiring direct, consented authentication input.

Content

Scanner excerpt · references/figma-mcp-usage.md (reported line 7)May include surrounding context.

md
## Prerequisites

Figma MCP token is stored in `~/.claude/.credentials.json` under `mcpOAuth.figma*`.

`fetch_figma_mcp.py` now auto-refreshes near-expiry tokens when running with `--allow-claude-credentials`.

MCP Config Access

High
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · references/figma-mcp-usage.md (reported line 92)May include surrounding context.

md
| Action | Description | Required Args |
|---|---|---|
| `tools` | List available MCP tools | (none) |
| `info` | File/user info via whoami | `--file-key` |
| `metadata` | Node structure as XML-like markup | `--file-key --node-id/--node-ids` |
| `screenshot` | PNG screenshot of one or many nodes | `--file-key --node-id/--node-ids` |

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/figma-mcp-usage.md (reported line 175)May include surrounding context.

md
| Feature | MCP | REST API |
|---|---|---|
| Auth | OAuth (via Claude CLI) | Personal Access Token |
| Node structure | XML-like markup | Full JSON with all properties |
| Screenshots | Built-in `get_screenshot` | Separate `/images/` endpoint |
| CSS extraction | Use `figma_to_css.py` on REST JSON | Direct from REST JSON |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/auth_session_guard.py (reported line 37)May include surrounding context.

python
def sh(command: str) -> str:
    return subprocess.run(
        command,
        shell=True,
        stdout=subprocess.PIPE,

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This script manages Claude OAuth login state and callback verification, which is unrelated to the declared Figma-to-static HTML/CSS conversion purpose of the skill. Hidden authentication-handling code broadens the skill’s privilege and attack surface, and in this context suggests undocumented credential or session-flow manipulation that a user would not reasonably expect from a design-to-code tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file is clearly unrelated to the declared Figma-to-static purpose and instead classifies Claude REPL authentication/onboarding states to determine when it is 'safe' to request and submit auth artifacts like code#state. In the context of an agent skill, this creates a strong capability for credential harvesting or guided account takeover by helping route sensitive authentication data into a live terminal session.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code explicitly makes auth-handling decisions, including whether it is 'Safe to ask user for code#state and inject it into this same session,' which operationalizes the collection and use of authentication secrets. Because the skill's stated purpose is design-to-HTML conversion, this functionality is unjustified and materially increases the risk of phishing, session hijacking, or unauthorized access to Claude accounts.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The default credential path points at ~/.claude/.credentials.json, indicating built-in access to another application's stored secrets. In an agent skill, defaulting to a shared credential store materially increases danger because the skill may gain access to tokens the user did not intend to expose to this workflow.

Content

Scanner excerpt · scripts/fetch_figma_mcp.py (reported line 30)May include surrounding context.

python
MCP_URL = "https://mcp.figma.com/mcp"
PROTOCOL_VERSION = "2025-03-26"
DEFAULT_CRED_PATH = os.path.expanduser("~/.claude/.credentials.json")
TOKEN_REFRESH_MARGIN_MS = 2 * 60 * 1000
DEFAULT_AUTH_SERVER = "https://api.figma.com"

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/fetch_figma_mcp.py (reported line 226)May include surrounding context.

python
print("", file=sys.stderr)
    print("Run this script with one of these explicit auth modes:", file=sys.stderr)
    print("  A) export FIGMA_MCP_TOKEN=<token>  (recommended explicit mode)", file=sys.stderr)
    print("  B) --allow-claude-credentials      (read ~/.claude/.credentials.json)", file=sys.stderr)
    print("", file=sys.stderr)
    print("If callback is rejected as invalid/stale, restart login and use only the newest authorize URL.", file=sys.stderr)
    print("Optional state check:", file=sys.stderr)

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/fetch_figma_mcp.py (reported line 443)May include surrounding context.

python
print("", file=sys.stderr)
    print("Run this script with one of these explicit auth modes:", file=sys.stderr)
    print("  A) export FIGMA_MCP_TOKEN=<token>  (recommended explicit mode)", file=sys.stderr)
    print("  B) --allow-claude-credentials      (read ~/.claude/.credentials.json)", file=sys.stderr)
    print("", file=sys.stderr)
    print("If callback is rejected as invalid/stale, restart login and use only the newest authorize URL.", file=sys.stderr)
    print("Optional state check:", file=sys.stderr)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
97% confidence
Finding

The skill requests and orchestrates shell, network, filesystem, environment, and credential-adjacent capabilities but does not declare an explicit tool/permission scope. That creates a least-privilege failure: a user invoking a design-conversion skill would not be clearly informed that it can inspect local auth state, read config paths, install tooling, and access network resources.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- Request the **full callback URL** only when debugging state mismatch or localhost redirect failures.
- If the CLI already displayed an authorize URL, copy it exactly from tool output or extract it with `scripts/extract_auth_url.py`; never hand-retype long URLs.
- Before opening a fresh login flow, run `scripts/auth_session_guard.py` to detect conflicts or stale state.
- **Do not ask the user for `code#state` until REPL state is explicitly verified as `waiting-for-code`.**
  - Scrape the current REPL output.
  - Classify it with `python3 scripts/claude_repl_state.py --stdin`.
  - Only if `safeForCodeSubmission=true`, lock the auth URL/state and ask the user for code.