GitHub Advisoryadvisory · npm

GHSA-wmpw-j6qv-mw88 Quasar Framework: Path Traversal / Arbitrary File Write via crafted Icon Genie profile

HIGH Published 2026-10-07 Modified 2026-10-07 Official page ↗
Aliases
CVE-2026-106103
Ecosystem
npm
Packages
@quasar/icongenie
Severity
High
CVSS vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H
Weaknesses
CWE-22, CWE-73
Reviewed
2026-10-07

Affected packages

• npm @quasar/icongenie: < 6.1.1 → fixed in 6.1.1

Description

Vulnerability Details File: `icongenie/lib/utils/get-assets-files.js` (line 35, `absoluteName: join(appDir, asset.folder, asset.name)`) Validation gap: `icongenie/lib/utils/validate-profile-object.js` (`assetsSchema`) — `folder`/`name` only checked with `Joi.string().required().min(1)`, no restriction on `..` sequences or absolute paths Entry point: `icongenie/lib/runner/generate.js` (`generate(argv)`) — `profile.assets = userProfile.assets`, loaded verbatim from a user-supplied JSON file via `--profile ` Root Cause `icongenie generate --profile ` loads a JSON "profile" describing icon/splashscreen assets to generate, where each asset entry has a `folder`/`name` describing where the generated file should be written relative to the Quasar project directory (`appDir`). `getAssetsFiles()` builds the write target with `join(appDir, asset.folder, asset.name)`. Node's `path.join` normalizes `..` segments arithmetically and does not clamp the result to stay inside `appDir`. The only validation before this (`validateProfileObject` → Joi `assetsSchema`) checks that `folder`/`name` are non-empty strings, with no `..` rejection and no containment check against `appDir`. A profile setting `folder: "../../../../../../tmp/pwned-by-icongenie"` sails through validation unmodified, and the generator writes attacker-influenced icon/splashscreen content to that path via a direct `writeFile`/`sharp().toFile()` call. Attack Scenario 1. Attacker publishes a "ready-made Icon Genie profile" (gist, starter-kit repo, support forum attachment) that looks like a normal icon-generation config but includes an asset entry with a traversal `folder`. 2. A developer working on a Quasar project runs `icongenie generate --profile malicious-profile.json` (a normal, documented workflow) inside their project. 3. `getAssetsFiles()` resolves the write target outside the project directory; the generator writes attacker-controlled content to that path — e.g. planting/overwriting shell startup files, cron entries, or CI/build scripts. Impact • Type: CWE-22 Path Traversal / Arbitrary File Write • Auth required: No network auth — local CLI trust; requires the developer to run icongenie against a profile they didn't fully author/audit themselves • Consequence: Arbitrary file write/overwrite at any path the running user can write to, scoped by the number of `..` segments — can lead to persistence (cron/shell rc file) or supply-chain-style code execution if the written file is later executed/sourced. Vulnerable Code (`icongenie/lib/utils/get-assets-files.js`) ```js export function getAssetsFiles(assets) { ... return list.map(({ tag, ...asset }) => { const file = { ...asset, relativeName: join(asset.folder, asset.name), absoluteName: join(appDir, asset.folder, asset.name) // no containment check } ... }) } ``` Recommended Fix ```js import { resolve, sep } from 'node:path' const absoluteName = resolve(appDir, asset.folder, asset.name) if (absoluteName !== appDir && !absoluteName.startsWith(appDir + sep)) { fatal(`Profile asset escapes the project folder: "${asset.folder}/${asset.name}"`) } ``` Verification Confirmed end-to-end on v2.21.1 by running the real, unmodified `icongenie generate()` function (from `icongenie/lib/runner/generate.js`) against a scratch Quasar project containing a crafted `malicious-profile.json` with `"folder": "../../outside-target-marker"`. icongenie's own console output self-reported the traversal (`Generated svg: ../../outside-target-marker/pwned-outside-project.svg`), and the generated SVG file was independently verified on disk two directory levels outside the project folder. A fix branch (`fix/icongenie-path-traversal-asset-folder`) is ready with the minimal patch above. Re-running the same malicious profile against the patched code now aborts immediately with `Profile asset escapes the project folder: "../../outside-target-marker/pwned-outside-project.svg"` and writes nothing outside the project, while a legitimate profile (`folder: "public/icons"`) continues to work exactly as before.

Related

Alias · CVE (1)

  • CVE-2026-106103 Quasar Framework is a framework for building high-performance Vue.js user interfaces. vulnerability

Weakness · CWE (2)

  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness
  • CWE-73 External Control of File Name or Path weakness

References