Back to skill

Security audit

Photoshop Automator

Security checks for vulnerabilities and agentic risk

Overview

This Photoshop automation skill is disclosed and purpose-aligned, but it gives agents broad raw scripting and filesystem power without built-in safeguards.

Install only if you trust the agents and workflows that will call it to run local Photoshop scripts. Treat runScript as powerful local automation, review every script before execution, use explicit export paths in non-sensitive directories, and prefer adding an allowlist, confirmation step, path validation, overwrite checks, and safer temporary-file creation before unattended use.

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
handler.js:47
Finding
Predictable, Non-Exclusive Temporary Files Permit Arbitrary File Overwrite## Vulnerability Details **File Location**: `handler.js`, lines 47–57 **Vulnerability Type**: Insecure temporary-file creation **Risk Level**: Medium ### Vulnerable Code ```js const tempDir = os.tmpdir(); const timestamp = Date.now(); const jsxPath = path.join(tempDir, `ps_script_${timestamp}.jsx`); fs.writeFileSync(jsxPath, ctx.params.script); let result; if (isWin) { const vbsPath = path.join(tempDir, `ps_bridge_${timestamp}.vbs`); fs.writeFileSync(vbsPath, VBS_CONTENT); ``` ### Technical Analysis The Skill constructs temporary JSX and VBS paths from `Date.now()`, making their names predictable to another process on the same host. It then creates or truncates these files using `fs.writeFileSync` without exclusive creation. Because the operating-system temporary directory may be shared among users or processes, a local attacker can predict candidate filenames and pre-create symbolic links at those paths. When the Skill writes the temporary content, the write operation can follow the symbolic link and overwrite its target with the privileges of the Agent process. This is a time-of-check/time-of-use-style temporary-file vulnerability; no separate validation step prevents link traversal or an existing path from being reused. ### Attack Path 1. A local attacker monitors the clock and predicts upcoming names such as `ps_script_<timestamp>.jsx` or `ps_bridge_<timestamp>.vbs`. 2. The attacker creates candidate symbolic links in the shared temporary directory before the Skill writes its files. 3. Each symbolic link points to a file the Agent process can modify. 4. A user or automated workflow invokes `runScript`. 5. `fs.writeFileSync` follows the attacker-created link and truncates or overwrites the selected target. 6. Depending on the target, the attacker can cause data loss, configuration manipulation, or execution of attacker-influenced content by another component. The exploit requires ...[truncated 724 chars]
Remediation
## Remediation Suggestions 1. Create a uniquely named private temporary directory with `fs.mkdtempSync(path.join(os.tmpdir(), 'photoshop-automator-'))`. 2. Store the JSX and VBS files inside that private directory using fixed internal names. 3. Create files exclusively with `flag: 'wx'` so existing paths are rejected rather than truncated. 4. Apply restrictive permissions, such as mode `0o600` for files and `0o700` for the directory where supported. 5. Place execution and cleanup in a `try`/`finally` block so all temporary artifacts are removed on success, process-launch failure, or unexpected exceptions. 6. Reject symbolic links or unexpected pre-existing entries if compatibility constraints prevent use of a private directory. 7. Avoid relying on timestamps alone for uniqueness; use operating-system-backed secure temporary creation. Example hardening pattern: ```js const tempRoot = fs.mkdtempSync( path.join(os.tmpdir(), 'photoshop-automator-') ); try { const jsxPath = path.join(tempRoot, 'script.jsx'); fs.writeFileSync(jsxPath, ctx.params.script, { flag: 'wx', mode: 0o600 }); // Create the bridge with the same exclusive and restrictive options. // Execute Photoshop automation here. } finally { fs.rmSync(tempRoot, { recursive: true, force: true }); } ```
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill metadata and description understate the actual capability surface: beyond helper-style Photoshop automation, it exposes arbitrary ExtendScript execution via runScript, filesystem-affecting export behavior, layer creation, and macOS osascript usage. In an agent setting, this mismatch is dangerous because operators or downstream tooling may grant trust based on the declared scope while the skill can perform broader local actions, including file reads/writes through Photoshop's scripting engine.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The runScript command accepts arbitrary JSX from the caller and executes it in Photoshop without restriction. ExtendScript can manipulate files, invoke application actions, and perform operations far beyond the advertised text, filter, and action helpers, so this materially expands the skill’s authority and creates a powerful code-execution primitive inside the host application.

Missing User Warnings

High
Confidence
97% confidence
Finding
Arbitrary Photoshop scripting is executed immediately with no user-facing warning, review, or confirmation. In this context, that is dangerous because the skill is presented as an automation tool for limited editing tasks, yet it silently grants the caller the ability to run powerful scripts that can alter documents, access files through Photoshop scripting, or trigger other destructive actions.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The skill writes temporary bridge scripts and invokes system script interpreters (cscript/osascript) to drive Photoshop. While this is partly necessary for COM/AppleScript automation, it increases attack surface because untrusted input is funneled into local script execution paths and creates additional opportunities for abuse, persistence, or environment-specific exploitation if combined with the arbitrary JSX capability.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The export command writes to an arbitrary caller-supplied filesystem path without confirmation or restriction. That can be abused to overwrite user files, write into sensitive locations the process can access, or exfiltrate document contents to attacker-chosen destinations, which is more concerning in an automation skill that may be triggered indirectly.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
handler.js:57

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
handler.js:125