Back to skill

Security audit

qrcode-remote

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent QR-code tool, but it can automatically install dependencies, send user QR data or local images to a third-party service, and overwrite spreadsheet files in ways users should review first.

Install only if you are comfortable with QR contents and some local images being sent to api.2dcode.biz during generation or decode fallback. Avoid using it on confidential QR codes or sensitive screenshots unless you disable or manually control remote fallback. Back up spreadsheets before batch decoding, prefer TXT output where possible, and install dependencies yourself in an isolated environment with pinned versions.

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 (5)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:28
Finding

Automatic Installation of Unpinned Third-Party Dependencies

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch_decode.py:192
Finding

Spreadsheet Formula Injection Through Decoded QR-Code Content

Content
View full analysis
r.push(decoded[i])); const csvContent = [headers, ...dataRows] .map((r) => r.map((c) => `"${String(c).replace(/"/g, '""')}"`).join(",")) .join("\n"); fs.writeFileSync(inputPath, "\uFEFF" + csvContent, "utf-8"); ``` ### Technical Analysis Decoded QR-code text is attacker-controlled. Both implementations write that content directly into spreadsheet cells without neutralizing formula metacharacters. A value beginning with `=`, `+`, `-`, or `@` may be interpreted as a formula by spreadsheet applications. Quoting a CSV field does not reliably prevent formula evaluation. For XLSX output, assigning a string beginning with `=` through OpenPyXL may create ...[truncated 1597 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch_decode.js:249
Finding

Destructive Replacement of Existing Excel Workbooks

Content
View full analysis
r.push(decoded[i])); const allRows = [headers, ...dataRows]; const wb = XLSX.utils.book_new(); const ws = XLSX.utils.aoa_to_sheet(allRows); XLSX.utils.book_append_sheet(wb, ws); XLSX.writeFile(wb, inputPath); return { total: dataRows.length, success, failed: dataRows.length - success, output_file: path.resolve(inputPath), output_txt: null }; ``` The input-reading path only extracts the first sheet: ```javascript const wb = XLSX.readFile(fp); return XLSX.utils .sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1, defval: "" }) .map((r) => r.map((c) => String(c ?? ""))); ``` ### Technical Analysis The Node.js implementation does not modify the existing workbook. It converts the first worksheet to a plain two-dimensional array, constructs a completely new workbook containing one newly generated worksheet, and then writes that workbook over the original input path. This conversion discards information not represented by the value array, including: - All worksheets other than the first one - Formulas and formula metadata - Cell formatting and number formats - Charts, drawings, images, comments, and hyperlinks - Named ranges, validations, filters, and workbook metadata - Macros or other unsupported workbook features - Original sheet name and workbook structure The behavior contradicts the documented promise to add a decode-result column to the original workbook. ### Attack Path 1. A user supplies an existing `.xlsx` or `.xls` workbook containing multiple sheets, formulas, formatting, or other important workbook features. 2. The user invokes the Node.js batch decoder without `--output-txt`. 3. The script reads values from only the first worksheet. 4. It creates a new single-sheet workbook ...[truncated 615 chars]
Remediation
View remediation
_decoded.xlsx`. 4. Require an explicit `--overwrite` option before modifying the original file. 5. Create a backup before any in-place update. 6. Write to a temporary file first, verify that it can be reopened, and then perform an atomic replacement. 7. Preserve sheet names, all worksheets, cell types, formulas, formatting, and workbook metadata. 8. Reject formats or workbook features that the selected library cannot safely preserve. 9. Add regression tests using multi-sheet workbooks with formulas, formatting, charts, comments, hyperlinks, and named ranges. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/decode.js:37
Finding

Unbounded Remote Downloads and Image Processing

Content
View full analysis
{ const mod = url.startsWith("https") ? https : http; mod.get(url, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { return httpGet(res.headers.location).then(resolve, reject); } const chunks = []; res.on("data", (c) => chunks.push(c)); res.on("end", () => resolve(Buffer.concat(chunks))); }).on("error", reject); }); } 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.createWriteStream(tmp); mod.get(url, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { file.close(); fs.unlinkSync(tmp); return downloadToTemp(res.headers.location).then(resolve, reject); } res.pipe(file); file.on("finish", () => { file.close(); resolve(tmp); }); }).on("error", (e) => { file.close(); if (fs.existsSync(tmp)) fs.unlinkSync(tmp); reject(e); }); }); } ``` `scripts/decode.py:25-42`: ```python def download_image(url: str) -> str: """Download an image to 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. ...[truncated 2153 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/decode.py:145
Finding

Automatic Disclosure of Local Images to a Third-Party API

Content
View full analysis
Remediation
View remediation
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 (107)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The analyzer's statement that decoding is not implemented cannot be confirmed from SKILL.md alone, but the provider mismatch is real and important. Misstating the backend service can lead to incorrect trust decisions and compliance assumptions about where data is sent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill directs automatic execution of pip/npm installation commands without user approval. Installing dependencies at runtime introduces supply-chain risk, allows arbitrary code execution from package install scripts, and expands system state beyond the user's original request.

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/generate.py ...` | `node scripts/generate.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/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 48)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 49)May include surrounding context.

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

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

When local generation fails, the script silently falls back to the remote API and transmits the QR payload externally without separate consent or notice. This is more dangerous than explicit API mode because users may believe processing is local while confidential data is unexpectedly disclosed to a third party.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill metadata says it uses the CaoLiao QR Code API, but the code actually sends user data to a different third-party endpoint, api.2dcode.biz. This creates a trust-boundary violation: users and reviewers may approve the skill based on one service while sensitive QR payloads are transmitted to another service with potentially different privacy, logging, retention, or legal controls.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

md
## Security

- **Privacy**: QR code images uploaded to the server for decoding are temporary files that are automatically deleted after a period of time. No long-term storage of your images.
- **Transparency**: All third-party libraries used (zxingcpp, Pillow, qrcode, CaoLiao API, etc.) are public and open-source. You can audit the dependencies yourself.
- **Local-first**: Decoding is performed locally by default. Remote API is only used when local decoding fails, minimizing data transmission.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README advertises local file saving, ZIP creation, and spreadsheet write-back, but does not prominently warn that user files may be created or modified. In an agent skill, unclear disclosure of data-changing behavior can lead to unintended overwrites, corruption of user data, or actions taken without informed consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The phrase "Generate a QR code for me" is broad enough to trigger the skill on commonplace requests, potentially causing the agent to invoke networked or file-writing functionality without the user understanding the side effects. In this skill context, broad activation is more risky because the tool can generate remote URLs, download files, and process local data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The example shows QR generation via a third-party API URL containing user-supplied data in the query string. If users encode sensitive text, URLs, tokens, or internal links, that data is transmitted to an external service and may be logged by intermediaries, browsers, or the provider.

Content

Scanner excerpt · README.md (reported line 89)May include surrounding context.

md
> **AI:** QR code generated:
>
> ![QR Code](https://api.2dcode.biz/v1/create-qr-code?data=https%3A%2F%2Fcli.im&size=400x400)
>
> **QR Code URL:** `https://api.2dcode.biz/v1/create-qr-code?data=https%3A%2F%2Fcli.im&size=400x400`

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This line repeats the externally hosted QR code URL, again embedding the encoded content directly in a third-party request. In this skill context, the danger is heightened because users may assume QR generation is local while the example normalizes remote disclosure of the payload.

Content

Scanner excerpt · README.md (reported line 91)May include surrounding context.

md
>
> ![QR Code](https://api.2dcode.biz/v1/create-qr-code?data=https%3A%2F%2Fcli.im&size=400x400)
>
> **QR Code URL:** `https://api.2dcode.biz/v1/create-qr-code?data=https%3A%2F%2Fcli.im&size=400x400`

---

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The saved-local example still relies on a remote API URL that includes the encoded text before downloading the image locally. This can mislead users into thinking the operation is private because the final artifact is local, even though the payload was first transmitted externally.

Content

Scanner excerpt · README.md (reported line 103)May include surrounding context.

md
>
> QR code generated and saved locally:
>
> **QR Code URL:** `https://api.2dcode.biz/v1/create-qr-code?data=Hello%20World&size=400x400&format=svg`
> **Local file:** `C:\Users\xxx\Desktop\qrcode.svg`

---

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.