Back to skill

Security audit

qrcode

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its QR-code purpose, but it needs review because it auto-installs mutable dependencies, fetches arbitrary remote URLs, and writes untrusted decoded content back into spreadsheets.

Review before installing. Use local image files instead of remote URLs when possible, run it in a restricted environment, avoid opening generated CSV/XLSX results from untrusted QR sources without checking for formulas, back up batch input files before decoding, and pin or manually review dependencies before allowing installation.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/decode.py:20
Finding

Unrestricted URL Fetching Enables SSRF and Resource Exhaustion

Content
View full analysis
bool: return s.startswith("http://") or s.startswith("https://") def download_image(url: str) -> str: """Download an image into a temporary file and return its path.""" import urllib.request suffix = Path(url.split("?")[0]).suffix or ".png" tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix) try: urllib.request.urlretrieve(url, tmp.name) except Exception as e: tmp.close() os.unlink(tmp.name) raise RuntimeError(f"Image download failed: {e}") tmp.close() return tmp.name ``` Python batch decoder: ```python def _is_url(s: str) -> bool: return s.startswith("http://") or s.startswith("https://") def _try_zxing(source: str) -> str | None: try: import zxingcpp from PIL import Image except ImportError: return None tmp_path = None try: if _is_url(source): import urllib.request suffix = Path(source.split("?")[0]).suffix or ".png" tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix) urllib.request.urlretrieve(source, tmp.name) tmp.close() tmp_path = tmp.name img_path = tmp_path ``` Node.js single-image decoder: ```javascript function isUrl(s) { return s.startsWith("http://") || s.startsWith("https://"); } function downloadToTemp(url) { return new Promise((resolve, reject) => { const ext = path.extname(url.split("?")[0]) || ".png"; const tmp = path.join(os.tmpdir(), `qr_${Date.now()}${ext}`); const mod = url.startsWith("https") ? https : http; const file = fs. ...[truncated 3890 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch_decode.py:119
Finding

Attacker-Controlled QR Content Is Written to Spreadsheets Without Formula Neutralization

Content
View full analysis
r.push(decoded[i])); const csvContent = [headers, ...dataRows] .map((r) => r.map((c) => `"${String(c).replace(/"/g, '""')}"`).join(",")) .join("\n"); ...[truncated 2319 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:24
Finding

Automatic Installation Uses Unpinned and Unlocked Third-Party Dependencies

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/decode.js:33
Finding

Predictable Temporary Filename Permits Local Symlink File Clobbering

Content
View full analysis
{ const ext = path.extname(url.split("?")[0]) || ".png"; const tmp = path.join(os.tmpdir(), `qr_${Date.now()}${ext}`); const mod = url.startsWith("https") ? https : http; const file = fs.createWriteStream(tmp); mod.get(url, (res) => { ``` ### Technical Analysis The single-image Node.js decoder creates a temporary path from the current timestamp and a URL-derived extension. It does not use a private temporary directory, cryptographically unpredictable filename, or exclusive file creation. `fs.createWriteStream` opens an existing path for writing by default and may follow a symbolic link. On a multi-user system, a local attacker able to write to the shared temporary directory could predict or race the timestamp-based filename and create a symbolic link at that path. When the decoder opens the path, downloaded data may be written to the symlink target. Exploitation requires local access and successful timing or filename prediction, so the practical risk is lower than the remotely triggerable issues. ### Attack Path 1. A local attacker monitors or predicts when the decoder will run. 2. The attacker creates a symbolic link in the shared temporary directory using the expected timestamp-based filename. 3. The symlink points to a file writable by the Agent account. 4. The decoder calls `fs.createWriteStream` on the predictable path. 5. The runtime follows the symbolic link and truncates or overwrites the target with downloaded bytes. ### Impact Assessment The attacker may overwrite or corrupt files writable by the user running the Skill. The vulnerability does not independently bypass operating-system permissions and cannot overwrite files that the Agent account cannot modify. Th ...[truncated 99 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (73)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the underlying decoder can process more than QR codes, the skill's QR-only framing is imprecise and may mislead users about the breadth of data it can extract. This is lower impact than the network and file-write issues, but still a documentation mismatch that affects informed consent and policy gating.

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

md
| 单个解码 | `python scripts/decode.py ...` | `node scripts/decode.js ...` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 批量生成 | `python scripts/batch_generate.py ...` | `node scripts/batch_generate.js ...` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 批量解码 | `python scripts/batch_decode.py ...` | `node scripts/batch_decode.js ...` |

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The header comment says the tool performs local decoding, but the implementation downloads remote images when a URL is supplied. This misleading description can cause users to run the script in sensitive environments under false assumptions, increasing the risk of unwanted data egress and network exposure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script accepts URL values from input data and downloads them over HTTP/HTTPS, which contradicts the skill’s stated local-only behavior and expands its trust boundary to the network. This can leak user IP/addressing metadata to attacker-controlled hosts, enable SSRF-like access to internal resources if the environment has network reachability, and process untrusted remote content without restrictions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that remote image URLs may be downloaded locally for decoding, but it does not prominently warn users that this causes outbound network access and local file handling of untrusted content. In a skill context, that matters because users may assume 'fully local' means no network activity at all, and remote fetches can expose metadata, hit internal resources if misused, or process malicious files.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding

The README instructs users to run npx skills add ... without pinning the version of the skills package or otherwise constraining the fetched code. Because npx resolves and executes packages dynamically, users may receive a newer or compromised package version than expected, creating a supply-chain execution risk during installation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding

This installation command uses npx skills add ... without a pinned version for the skills executable. That means installation behavior depends on whatever version is current at execution time, increasing exposure to malicious or breaking upstream changes in the package supply chain.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding

The global install example invokes npx skills without a version pin, which causes remote package resolution at runtime. If the upstream package is hijacked or updated unexpectedly, users could execute unintended code during installation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding

The agent-specific installation example also relies on an unpinned npx skills invocation. In security terms this is a supply-chain risk because the command implicitly trusts whatever package version the registry serves at that moment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding

This command repeats the same unpinned npx skills pattern, which is risky because it executes code fetched on demand from the package ecosystem. Even though the README appears benign, dynamic unpinned bootstrap commands are a common route for supply-chain compromise.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction to trigger the skill by asking the agent "Generate a QR code for me" is broad and does not define boundaries or exclusion conditions. While QR-related, it serves as the primary activation guidance and lacks any narrowing context or negative examples, which could lead to unintended invocation for loosely related requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that when decoding a remote image URL, the skill will download the image locally, but it does not present this network access as a prominent warning to users. This can lead to unexpected outbound requests, privacy leakage, SSRF-style access to internal resources if arbitrary URLs are accepted, and processing of untrusted remote content.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

The README instructs users to run npx skills add ... without pinning the version of the skills package. This creates a supply-chain risk because a future compromised or maliciously updated package version could be fetched and executed at install time. In a skill installation context, this is more dangerous because users are explicitly encouraged to execute the command directly from the documentation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

This installation example uses npx skills add without pinning the version of the invoked package, exposing users to unreviewed upstream changes or package compromise. Because npx may download and execute code on demand, the risk is a practical supply-chain execution issue rather than a purely informational concern.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

The documented global install command relies on an unpinned npx skills invocation. If the package or one of its transient dependencies is hijacked, users could execute attacker-controlled code during setup, and global installation may broaden system impact.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

This command again uses npx skills add without constraining the installer version, leaving the setup path dependent on whatever package version npm resolves at the time. In security-sensitive environments, such floating installer references are a recognized supply-chain weakness.

Content

No source excerpt is available for this finding.