Back to skill

Security audit

Figma

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for Figma read/export work, but its export path can overwrite local files and its main skill instructions understate some Figma account and team enumeration capabilities.

Install only if you are comfortable giving the agent a Figma token that can read the relevant files, comments, projects, and account metadata. Use a least-privilege token, run exports from a clean directory, and watch for existing files named like figma_export_<layer_id>.<format> because exports can overwrite them.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/figma_tool.py:108
Finding
Predictable Export Filename Allows File Clobbering and Symlink-Following Writes## Vulnerability Details **File Location**: `scripts/figma_tool.py`, lines 108–115 **Vulnerability Type**: Unprotected file overwrite and unsafe filename handling **Risk Level**: Medium ```python # Sanitize layer_id for filename safe_id = layer_id.replace(":", "_") filename = f"figma_export_{safe_id}.{args.format}" try: with urllib.request.urlopen(image_url) as response: with open(filename, "wb") as f: f.write(response.read()) print(f"Saved to {filename}") ``` ### Technical Analysis The export destination is predictable and is opened with `open(filename, "wb")`. This mode silently truncates existing files and follows symbolic links. The code neither checks whether the destination already exists nor ensures that it is a regular file inside a trusted export directory. Filename sanitization only replaces colon characters. It does not apply a strict character allowlist, reject path separators, normalize the resulting path, or verify that the resolved destination remains inside an authorized directory. A local attacker with write access to the working directory can prepare a symbolic link using the predictable export filename. When the Skill exports the corresponding layer, Python follows that link and overwrites its target with attacker-selected Figma image content. Exploitation remains limited by the filesystem permissions of the process running the Skill. This finding is separate from the expected network behavior. The audited code sends `FIGMA_TOKEN` only to the fixed official HTTPS Figma API endpoint, and it does not attach the token when downloading returned image URLs. That network access is necessary for the declared functionality and was not identified as credential exfiltration. ### Attack Path 1. An attacker obtains write access to the directory from which the Skill will run. 2. The attacker predicts the destination name from the layer ID and format, such as `figma_export_123_45 ...[truncated 1210 chars]
Remediation
## Remediation Suggestions 1. Write exports into a dedicated directory whose ownership and permissions are controlled by the Skill. 2. Normalize layer identifiers using a strict allowlist, such as ASCII letters, digits, underscores, and hyphens. Reject path separators and special path components. 3. Resolve the final destination and verify that it remains within the intended export directory. 4. Create files atomically and exclusively using `open(path, "xb")`, or use `os.open` with `O_CREAT | O_EXCL` and, where supported, `O_NOFOLLOW`. 5. Refuse to overwrite existing files unless the user explicitly supplies an overwrite option. 6. Write to a securely created temporary file in the destination directory and atomically rename it only after a successful download. 7. Stream downloads in bounded chunks and enforce a maximum response size to reduce memory and disk-exhaustion risk. 8. Consider generating collision-resistant output names or requiring the caller to select an explicit, validated destination.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Credential Access

High
Category
Privilege Escalation
Content
## Setup

### Prerequisites
1. A **Figma Personal Access Token (PAT)**. You can generate one in your Figma account settings.
2. Python 3 installed on the host machine.

### Configuration
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Setup

### Prerequisites
1. A **Figma Personal Access Token (PAT)**. You can generate one in your Figma account settings.
2. Python 3 installed on the host machine.

### Configuration
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill invokes a Python script that uses both environment-provided secrets and network access, but the manifest does not declare any explicit tool scope or allowed-tools restrictions. That creates unnecessary ambient authority: an agent/runtime may permit broader execution than intended, increasing the blast radius if the script is modified, misused, or prompt-injected into performing unintended actions.

External Transmission

Medium
Category
Data Exfiltration
Content
self.token = token

    def _request(self, endpoint, params=None):
        url = f"https://api.figma.com/v1/{endpoint}"
        if params:
            url += "?" + urllib.parse.urlencode(params)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill description says it reads Figma files/comments and exports assets, but the implementation also exposes account introspection and team/project enumeration via get_me, get_team_projects, and get_project_files. This scope expansion can leak organizational metadata and enable broader reconnaissance than the user or platform expects, especially if an agent is granted a powerful FIGMA_TOKEN.

Static analysis

No suspicious patterns detected.