Back to skill

Security audit

Baoyu Compress Image

Security checks for vulnerabilities and agentic risk

Overview

This image-compression skill appears purpose-built, but it can change or overwrite image files by default and may fetch an unpinned runtime package if Bun is missing.

Review before installing. Use this only on copied or backed-up images, prefer --keep, avoid running recursive mode on important directories without checking outputs, and install Bun through a trusted pinned process rather than relying on npx -y bun. Treat project EXTEND.md files as untrusted unless you personally control them.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:18
Finding

Unpinned Runtime Package Download and Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 18
Vulnerability Type: Unpinned third-party package execution
Risk Level: Medium

Vulnerable Code

markdown
Scripts in `scripts/` subdirectory. `{baseDir}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.

Technical Analysis

When Bun is not installed, the skill instructs the agent to run npx -y bun. This command may download a package from the configured npm registry and execute it immediately without pinning an audited version or verifying an integrity hash. The -y option suppresses the interactive confirmation that would otherwise warn the user about package installation.

Consequently, the code executed by the skill can differ from the code originally reviewed. Exploitation would require compromise of the package publication channel, the registry, the relevant package-maintainer account, or the local npm registry configuration. A malicious registry configured in the execution environment could also supply attacker-controlled package content.

Attack Path

  1. Bun is not installed on the target system, but npx is available.
  2. The agent follows the skill instructions and resolves ${BUN_X} to npx -y bun.
  3. npx resolves the unpinned bun package through the environment's configured npm registry.
  4. A compromised publication channel, malicious registry, or altered registry configuration supplies attacker-controlled package code.
  5. npx downloads and executes the package without asking for confirmation.
  6. The package code runs with the permissions of the user or agent process.

Impact Assessment

Successful exploitation provides arbitrary code execution under the invoking user's privileges. The effective scope can include reading or modifying files accessible to ...[truncated 266 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not automatically download and execute a runtime through an unpinned npx command.
  • Prefer a preinstalled Bun binary obtained through a trusted installation process.
  • If package-based execution is unavoidable, pin an explicitly audited package version rather than resolving the latest available release.
  • Use a lockfile and registry integrity metadata where supported.
  • Validate the npm registry origin and prohibit project-controlled or untrusted registry overrides.
  • Avoid -y so that package installation remains visible and requires explicit user approval.
  • Document the expected Bun version and verify the executable or package checksum before use.

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:27
Finding

Project-Controlled Markdown Is Loaded as Skill Configuration

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 27-36
Vulnerability Type: Indirect prompt injection through an untrusted configuration file
Risk Level: Medium

Vulnerable Code

markdown
## Preferences (EXTEND.md)

Check EXTEND.md in priority order — the first one found wins:

| Priority | Path | Scope |
|----------|------|-------|
| 1 | `.baoyu-skills/baoyu-compress-image/EXTEND.md` | Project |
| 2 | `${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-compress-image/EXTEND.md` | XDG |
| 3 | `$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md` | User home |

If none found, use defaults.

Technical Analysis

The skill instructs the agent to read a project-controlled Markdown file and gives that file precedence over user-level preferences. Markdown is an instruction-capable natural-language format, but the skill does not define a strict parser, an allowlisted schema, or a rule requiring all non-configuration content to be ignored.

A repository author can therefore place agent-directed instructions in .baoyu-skills/baoyu-compress-image/EXTEND.md. If the agent interprets that Markdown as instructions rather than inert configuration data, it can alter the agent's behavior during the current session.

The TypeScript implementation does not itself load EXTEND.md; the exposure arises from the agent-facing instructions in SKILL.md. Exploitation therefore depends on the hosting agent following those instructions and treating the file's natural-language content as authoritative.

Attack Path

  1. An attacker creates or modifies a project supplied to the user.
  2. The attacker adds .baoyu-skills/baoyu-compress-image/EXTEND.md.
  3. The file contains legitimate-looking image preferences followed by malicious natural-language instructions.
  4. The user invokes the image-compression skill in that project.
  5. Following SKILL.md, the agent reads the project-level file before trusted u ...[truncated 739 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace Markdown-based preferences with a machine-readable format such as JSON.
  • Define and enforce a strict schema containing only the supported fields, such as format, quality, and keepOriginal.
  • Reject unknown keys, free-form text, nested instruction fields, and malformed values.
  • State explicitly that configuration content is untrusted data and must never be interpreted as agent instructions.
  • Parse the file programmatically in scripts/main.ts instead of asking the agent to interpret it.
  • Consider requiring explicit user approval before accepting project-level configuration that overrides trusted user preferences.
  • Constrain values to documented allowlists and ranges after parsing.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/main.ts:146
Finding

Predictable Temporary File and Unchecked Destination Replacement

Content
View full analysis

Vulnerability Details

File Location: scripts/main.ts, lines 146-159
Vulnerability Type: Unsafe temporary-file handling and file replacement
Risk Level: Low

Vulnerable Code

typescript
const absInput = resolve(input);
const inputSize = statSync(absInput).size;
const output = getOutputPath(absInput, opts.format, opts.keep, opts.output);
const tempOutput = output + ".tmp";

await compress(compressor, absInput, tempOutput, opts.format, opts.quality);

const outputSize = statSync(tempOutput).size;

if (!opts.keep && absInput !== output) {
  const ext = extname(absInput);
  const base = absInput.slice(0, -ext.length);
  renameSync(absInput, `${base}_original${ext}`);
}
renameSync(tempOutput, output);

Technical Analysis

The temporary output name is deterministically derived by appending .tmp to the destination path. The code neither creates this path atomically with exclusive semantics nor verifies that the path is a regular file rather than a symbolic link. The selected image backend is consequently asked to write directly to a predictable filesystem path.

The final output and _original backup paths are also used without collision checks or explicit overwrite authorization. Filesystem replacement behavior varies by platform, but on systems where rename operations replace existing destination files, preexisting output or backup files may be overwritten. If a selected compressor follows symbolic links for its output path, a pre-created temporary-path symlink may redirect writes to another file accessible to the invoking user.

Exploitation requires an attacker capable of writing in the output directory or otherwise manipulating these paths. This is most relevant in shared, attacker-controlled, or concurrently modified directories.

Attack Path

  1. The attacker obtains write access to the directory where an image will be processed.
  2. The attacker predicts the output and tempora ...[truncated 1122 chars]
Remediation
View remediation

Remediation Suggestions

  • Create temporary output files in the destination directory with cryptographically random names.
  • Use exclusive, atomic creation semantics so processing fails if the temporary path already exists.
  • Verify with lstat that temporary, output, and backup paths are not symbolic links.
  • Refuse to replace existing output and backup files unless the user supplies an explicit overwrite option.
  • Where supported, open the temporary file with no-follow protections and pass a safely controlled file descriptor to the processing backend.
  • Perform atomic final replacement only after validating that the generated object is a regular file owned or created by the current process.
  • Remove temporary artifacts in a finally block when compression, validation, or rename operations fail.
  • Avoid predictable _original names; either require an explicit backup path or generate a collision-resistant backup filename.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented description understates the skill's actual behavior, omitting capabilities like JPEG output, recursive directory processing, JSON output, and especially destructive filesystem changes when originals are not kept. This mismatch can cause users or higher-level agents to invoke the skill under false assumptions, increasing the chance of unintended bulk modification or data loss.

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 24)May include surrounding context.

md
| `scripts/main.ts` | Image compression CLI |

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The skill instructs users to run npx -y bun without pinning a specific version, which allows whatever package/version is current at execution time to be fetched and executed. That creates a supply-chain risk: a compromised or unexpected upstream release could run arbitrary code in the user's environment when invoking the skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The examples and behavior indicate originals may be replaced by default, but the documentation does not prominently warn that this is destructive behavior. In a file-processing skill, silent replacement is risky because users may unintentionally overwrite or rename large sets of files, particularly when combined with directory and recursive modes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill's stated purpose is image compression, but the implementation executes host binaries such as which, cwebp, convert, and sips via child_process. While tool-based compression can be an implementation choice, unrestricted subprocess execution is a materially stronger capability than the manifest communicates.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

By default, the skill does not preserve the original file in place; it renames the source to a new *_original name and writes the compressed output at the original path or a derived path. This is a destructive filesystem side effect that is not obvious from the skill description, and it can break downstream references, automation, or user expectations even if data is not fully deleted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill modifies files on disk without an upfront warning or confirmation: when keep is false, it renames the original before replacing it with the compressed output. For a tool advertised simply as "compress image," this can surprise users and cause loss of expected filenames, broken links, or unintended bulk changes during directory processing.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/main.ts:55