unified-invoice

PassAudited by VirusTotal on May 12, 2026.

Overview

Type: OpenClaw Skill Name: unified-invoice Version: 1.1.0 The skill is classified as suspicious due to significant input sanitization vulnerabilities. The `scripts/freelance-run.sh` script directly embeds user-provided arguments (e.g., `--service`, `--client`) into a generated Markdown file without proper escaping, creating a prompt injection risk if an AI agent processes this Markdown. Similarly, the `scripts/generate.js` script inserts user-provided input (e.g., `options.notes`, `item.name`) directly into HTML templates without sanitization, leading to HTML injection/XSS vulnerabilities in the generated HTML/PDF documents. These flaws allow for potential attacks but do not show clear evidence of intentional malicious behavior like data exfiltration or unauthorized remote control.

Findings (0)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

If a client, item, or notes field contains HTML or script-like content, it could run or trigger network/resource loads during PDF generation instead of being treated as plain invoice text.

Why it was flagged

Item names and notes are inserted directly into HTML without escaping, then the generated file is opened in Chromium for PDF conversion.

Skill content
<td>${item.name}</td> ... .replace(/{{notes}}/g, options.notes || ''); ... await page.goto(`file://${htmlPath}`
Recommendation

Escape all template variables, use an auto-escaping template engine, sanitize HTML, and consider disabling JavaScript or applying a restrictive CSP during PDF rendering.

What this means

A crafted client name could cause files to be created outside the intended output folder, or cause unexpected overwrite/create behavior for user-writable paths.

Why it was flagged

The client name is used directly in a filesystem path for generated output, without rejecting path separators or verifying the resolved path stays under OUTPUT_DIR.

Skill content
const filename = `${issueDate}-견적서-${client.name}`; const htmlPath = path.join(OUTPUT_DIR, `${filename}.html`); ... fs.writeFileSync(htmlPath, html, 'utf-8');
Recommendation

Convert client names to safe basenames, reject '/', '\\', '..', and control characters, and verify path.resolve(target).startsWith(path.resolve(OUTPUT_DIR)) before writing.

What this means

Client names, invoice amounts, totals, and file paths may persist in a shared local events area if this helper script is used.

Why it was flagged

The helper script writes invoice metadata to an events directory under the OpenClaw workspace, which may be consumed by other local automation.

Skill content
EVENTS_DIR="${EVENTS_DIR:-$WORKSPACE/events}" ... "client": "$CLIENT", "amount": $AMOUNT, "total": $TOTAL, "file": "$FILENAME"
Recommendation

Document this event emission clearly, provide an opt-out, minimize sensitive metadata, and ensure workspace event files are not shared more broadly than intended.

What this means

Business contact, banking, and client details can remain in the skill's local data files and may be included in generated documents.

Why it was flagged

The skill stores sender contact and bank-account-style information locally for reuse in generated invoices.

Skill content
"phone": "010-1234-5678", "email": "contact@mufism.com", "bankAccount": "우리은행 1002-123-456789"
Recommendation

Use real financial/contact data only in a trusted workspace, review generated documents before sharing, and avoid storing unnecessary sensitive details.

What this means

A future npm install may resolve a different dependency version than the one originally tested.

Why it was flagged

The npm dependency is allowed to float within a semver range, and no lockfile is present in the supplied manifest.

Skill content
"dependencies": { "puppeteer-core": "^23.0.0" }
Recommendation

Pin dependency versions and include a reviewed lockfile so installations are reproducible.