Back to skill

Security audit

pascal-3d

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a legitimate Pascal 3D/MCP integration, but its documented install path uses mutable preview/beta CLI distribution that can execute local code and is not tightly pinned in the runnable commands.

Review the setup commands before installing. Prefer a pinned Pascal CLI version or the preview archive only after verifying the hard-coded SHA-256 directly, avoid elevated installs, keep Pascal API keys in a secret manager or environment variable, and only authorize hosted or autonomous account setup when you want the agent to have that workspace access.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
references/setup.md:14
Finding
Mutable Beta Dependency Is Installed Globally with Lifecycle Scripts Enabled## Vulnerability Details **File Location**: `references/setup.md:11-15` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash The npm beta is suitable for its published tool contract: npm install --global @pascal-app/cli@beta pascal editor --no-open ``` ### Technical Analysis The setup workflow installs `@pascal-app/cli` through the mutable npm distribution tag `beta`. Distribution tags can be moved to a different package version after this Skill has been reviewed, so the code ultimately installed is not fixed by the audited repository. The installation command also leaves npm lifecycle scripts enabled. If the package, publisher account, or release process is compromised, lifecycle scripts can execute during installation. The resulting globally available `pascal` executable is then explicitly invoked. Although the documentation later states which version the tag currently resolves to, that statement does not constrain npm resolution at installation time and does not verify package integrity. ### Attack Path 1. An attacker compromises the npm publisher account, package release process, or another mechanism capable of modifying the `beta` distribution tag. 2. The attacker publishes a malicious release or redirects `beta` to a compromised version. 3. A user follows the documented command, causing npm to resolve the mutable tag at that time. 4. Malicious lifecycle scripts can execute during installation with the invoking user's privileges. 5. The user subsequently runs `pascal editor --no-open`, allowing a replaced CLI to execute again and access resources available to that user. ### Impact Assessment Successful exploitation can provide code execution with the privileges of the user running npm. Depending on that user's environment, the malicious package could access local Pascal project data, user-readable files, environment variables, MCP configur ...[truncated 301 chars]
Remediation
## Remediation Suggestions 1. Replace the mutable tag with an exact, reviewed package version: ```bash npm install --global --ignore-scripts @pascal-app/cli@1.0.0-beta.1 ``` 2. Use `--ignore-scripts` if the reviewed CLI does not require installation lifecycle scripts. 3. Publish and verify a cryptographic integrity value or signed provenance for the exact package artifact. 4. Avoid privileged installation. Prefer a user-owned installation prefix or a project-scoped, locked dependency. 5. Document upgrades as a separate review process rather than silently following changes to a distribution tag. 6. Verify the installed version before execution and fail closed if it differs from the reviewed version.

T08 · Insecure Dependencies

Warning
Location
references/setup.md:24
Finding
Preview Archive Is Verified Against a Checksum Downloaded from the Same Release Channel## Vulnerability Details **File Location**: `references/setup.md:24-40` **Vulnerability Type**: Insufficiently independent dependency integrity verification **Risk Level**: Medium ### Vulnerable Code ```bash PASCAL_PREVIEW_VERSION='1.0.0-beta.2.status.0' PASCAL_PREVIEW_PREFIX="${XDG_DATA_HOME:-$HOME/.local/share}/pascal-preview" PASCAL_PREVIEW_DOWNLOAD="$(mktemp -d)" cd "$PASCAL_PREVIEW_DOWNLOAD" curl --fail --location --remote-name \ "https://github.com/pascalorg/editor/releases/download/cli-v1.0.0-beta.2-status.0/pascal-app-cli-${PASCAL_PREVIEW_VERSION}.tgz" curl --fail --location --remote-name \ "https://github.com/pascalorg/editor/releases/download/cli-v1.0.0-beta.2-status.0/SHA256SUMS.txt" # macOS shasum -a 256 -c SHA256SUMS.txt # Linux: use `sha256sum -c SHA256SUMS.txt` instead. npm install --global --prefix "$PASCAL_PREVIEW_PREFIX" --ignore-scripts \ "./pascal-app-cli-${PASCAL_PREVIEW_VERSION}.tgz" ``` ### Technical Analysis The archive and `SHA256SUMS.txt` are downloaded from the same GitHub release location. Checking an artifact against a checksum delivered through the same potentially compromised release channel proves only that the two downloaded files agree; it does not independently authenticate the expected artifact. The document states the reviewed archive hash later at `references/setup.md:52`: ```text The expected archive SHA-256 is `15628baeeb174fb7786a1643db08f0554bf6d18afaaa3979f01922c5cd40019a`. ``` However, the executable setup commands do not compare the downloaded archive directly against that embedded value. Consequently, replacement of both the archive and checksum manifest could pass the documented verification. Use of `--ignore-scripts` appropriately prevents npm lifecycle scripts during this installation, but the installed executable is subsequently expected to be run. A malicious archive therefore still presents a code-execution risk when the CLI is invoked. # ...[truncated 1249 chars]
Remediation
## Remediation Suggestions 1. Compare the archive directly against the independently recorded expected hash before installation: ```bash EXPECTED_SHA256='15628baeeb174fb7786a1643db08f0554bf6d18afaaa3979f01922c5cd40019a' ACTUAL_SHA256="$(shasum -a 256 "pascal-app-cli-${PASCAL_PREVIEW_VERSION}.tgz" | awk '{print $1}')" test "$ACTUAL_SHA256" = "$EXPECTED_SHA256" || { echo "Pascal CLI archive integrity verification failed" >&2 exit 1 } ``` 2. On Linux, use the corresponding `sha256sum` command while retaining the same hard-coded expected digest. 3. Prefer a signed release manifest and verify its signature against a public key distributed independently of the GitHub release assets. 4. Continue using `--ignore-scripts` and the user-owned installation prefix. 5. Abort installation on every download, checksum, signature, or version mismatch. 6. Record a new digest and repeat source review for every preview update rather than trusting a mutable manifest from the release channel.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Ae1

High
Category
analysis-evasion
Content
3. Follow [references/setup.md](references/setup.md) for the selected path. Never move a local project to hosted storage or create an account merely to complete
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
Claude Code:

Plugin users set the key once in the configuration prompt shown when `pascal-agent-skills@pascal` is enabled. To add or change it later, reinstall with `claude plugin install pascal-agent-skills@pascal --config pascal_api_key=<key>`, or open `/plugin` in a session and use its configure flow; there is no `claude plugin config` command. The hosted tools then load under the plugin's `pascal-hosted` server beside the local `pascal` server, and Claude Code keeps the key in the OS keychain, falling back to `~/.claude/.credentials.json`, rather than writing it into `settings.json` or any project file.

Without the plugin, register the hosted endpoint manually:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The description includes broad trigger phrases such as 'use this skill whenever a user asks an agent to work in Pascal' and 'return a verified Pascal editor link,' which can cause the skill to be invoked for loosely related requests. Over-broad routing increases the chance that an agent connects to external/local MCP tooling, inspects projects, or initiates setup in situations where a narrower skill or no Pascal access was actually intended.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger evals repeatedly activate on broad references to 'Pascal' plus generic actions like connect, inspect, or set up, without tightly anchoring activation to the specific Pascal 3D/building-scene domain. This can cause the skill to trigger in unintended contexts involving other tools, projects, or meanings of 'Pascal', leading to inappropriate capability routing and possible unauthorized use of connected MCP/tooling.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The example explicitly instructs the agent to persist a returned credential in a host secret store or local credential file, but it does not require any user-facing disclosure, retention limits, or confirmation that long-term storage is acceptable. In the context of an autonomous agent account for a private project, silent credential persistence can create unintended ongoing access to a private Pascal workspace and increases the risk of later misuse, leakage, or cross-run access beyond what the user expected.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The query text explicitly requests a "Blender Python script," which hard-codes Python as the language. Under the policy, forcing a specific language without opt-in or documented justification is a natural-language policy issue, even when it appears inside an eval example.

Static analysis

No suspicious patterns detected.