[SECURITY] Fix Zip Slip Vulnerability#529
Merged
lvca merged 1 commit intoArcadeData:mainfrom Sep 23, 2022
Merged
Conversation
4611739 to
daa32da
Compare
This fixes a Zip-Slip vulnerability.
This change does one of two things. This change either
1. Inserts a guard to protect against Zip Slip.
OR
2. Replaces `dir.getCanonicalPath().startsWith(parent.getCanonicalPath())`, which is vulnerable to partial path traversal attacks, with the more secure `dir.getCanonicalFile().toPath().startsWith(parent.getCanonicalFile().toPath())`.
For number 2, consider `"/usr/outnot".startsWith("/usr/out")`.
The check is bypassed although `/outnot` is not under the `/out` directory.
It's important to understand that the terminating slash may be removed when using various `String` representations of the `File` object.
For example, on Linux, `println(new File("/var"))` will print `/var`, but `println(new File("/var", "/")` will print `/var/`;
however, `println(new File("/var", "/").getCanonicalPath())` will print `/var`.
Weakness: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Severity: High
CVSSS: 7.4
Detection: CodeQL (https://codeql.github.com/codeql-query-help/java/java-zipslip/) & OpenRewrite (https://public.moderne.io/recipes/org.openrewrite.java.security.ZipSlip)
Reported-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Bug-tracker: JLLeitschuh/security-research#16
Co-authored-by: Moderne <team@moderne.io>
e6d0b6d to
472e69c
Compare
Member
|
Thanks! |
Contributor
Author
|
Hi @lvca, Do you need any assistance with vulnerability disclosure/CVE issuance? If so, I'm more than happy to assist! |
Member
|
@JLLeitschuh any help is welcome ;-) |
mergify Bot
added a commit
that referenced
this pull request
Nov 19, 2025
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2. Changelog *Sourced from [js-yaml's changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md).* > [3.14.2] - 2025-11-15 > --------------------- > > ### Security > > * Backported v4.1.1 fix to v3 > > [4.1.1] - 2025-11-12 > -------------------- > > ### Security > > * Fix prototype pollution issue in yaml merge (<<) operator. > > [4.1.0] - 2021-04-15 > -------------------- > > ### Added > > * Types are now exported as `yaml.types.XXX`. > * Every type now has `options` property with original arguments kept as they were > (see `yaml.types.int.options` as an example). > > ### Changed > > * `Schema.extend()` now keeps old type order in case of conflicts > (e.g. Schema.extend([ a, b, c ]).extend([ b, a, d ]) is now ordered as `abcd` instead of `cbad`). > > [4.0.0] - 2021-01-03 > -------------------- > > ### Changed > > * Check [migration guide](https://github.com/nodeca/js-yaml/blob/master/migrate_v3_to_v4.md) to see details for all breaking changes. > * Breaking: "unsafe" tags `!!js/function`, `!!js/regexp`, `!!js/undefined` are > moved to [js-yaml-js-types](https://github.com/nodeca/js-yaml-js-types) package. > * Breaking: removed `safe*` functions. Use `load`, `loadAll`, `dump` > instead which are all now safe by default. > * `yaml.DEFAULT_SAFE_SCHEMA` and `yaml.DEFAULT_FULL_SCHEMA` are removed, use > `yaml.DEFAULT_SCHEMA` instead. > * `yaml.Schema.create(schema, tags)` is removed, use `schema.extend(tags)` instead. > * `!!binary` now always mapped to `Uint8Array` on load. > * Reduced nesting of `/lib` folder. > * Parse numbers according to YAML 1.2 instead of YAML 1.1 (`01234` is now decimal, > `0o1234` is octal, `1:23` is parsed as string instead of base60). > * `dump()` no longer quotes `:`, `[`, `]`, `(`, `)` except when necessary, [#470](https://redirect.github.com/nodeca/js-yaml/issues/470), [#557](https://redirect.github.com/nodeca/js-yaml/issues/557). > * Line and column in exceptions are now formatted as `(X:Y)` instead of > `at line X, column Y` (also present in compact format), [#332](https://redirect.github.com/nodeca/js-yaml/issues/332). > * Code snippet created in exceptions now contains multiple lines with line numbers. > * `dump()` now serializes `undefined` as `null` in collections and removes keys with > `undefined` in mappings, [#571](https://redirect.github.com/nodeca/js-yaml/issues/571). > * `dump()` with `skipInvalid=true` now serializes invalid items in collections as null. > * Custom tags starting with `!` are now dumped as `!tag` instead of `!<!tag>`, [#576](https://redirect.github.com/nodeca/js-yaml/issues/576). > * Custom tags starting with `tag:yaml.org,2002:` are now shorthanded using `!!`, [#258](https://redirect.github.com/nodeca/js-yaml/issues/258). > > ### Added > > * Added `.mjs` (es modules) support. > * Added `quotingType` and `forceQuotes` options for dumper to configure > string literal style, [#290](https://redirect.github.com/nodeca/js-yaml/issues/290), [#529](https://redirect.github.com/nodeca/js-yaml/issues/529). > * Added `styles: { '!!null': 'empty' }` option for dumper > (serializes `{ foo: null }` as "`foo:` "), [#570](https://redirect.github.com/nodeca/js-yaml/issues/570). ... (truncated) Commits * [`9963d36`](nodeca/js-yaml@9963d36) 3.14.2 released * [`10d3c8e`](nodeca/js-yaml@10d3c8e) dist rebuild * [`5278870`](nodeca/js-yaml@5278870) fix prototype pollution in merge (<<) ([#731](https://redirect.github.com/nodeca/js-yaml/issues/731)) * See full diff in [compare view](nodeca/js-yaml@3.14.1...3.14.2) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ArcadeData/arcadedb/network/alerts).
mergify Bot
added a commit
that referenced
this pull request
Apr 26, 2026
…o 5.21.0 in /studio [skip ci] Bumps [enhanced-resolve](https://github.com/webpack/enhanced-resolve) from 5.20.1 to 5.21.0. Release notes *Sourced from [enhanced-resolve's releases](https://github.com/webpack/enhanced-resolve/releases).* > v5.21.0 > ------- > > ### Minor Changes > > * Added promise API and support to resolve without `context` and `resolveContext`. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#520](https://redirect.github.com/webpack/enhanced-resolve/pull/520)) > * Add `extensionAliasForExports` option. When `true`, `extensionAlias` also applies to paths resolved through the `package.json` `exports` field. Off by default to match Node.js; opt in for full TypeScript-resolver parity with packages that ship `.ts` sources alongside the compiled `.js` they declare in `exports`. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#554](https://redirect.github.com/webpack/enhanced-resolve/pull/554)) > > ### Patch Changes > > * Properly handle DOS device paths (`\\?\…` and `\\.\…`). (by [`@alexander-akait`](https://github.com/alexander-akait) in [#551](https://redirect.github.com/webpack/enhanced-resolve/pull/551)) > * Prevent fallback to parent node\_modules when the `exports` field target file is not found. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#495](https://redirect.github.com/webpack/enhanced-resolve/pull/495)) > * Imports field spec deviation: non-relative targets (e.g. `"#a": "#b"`) no longer re-enter imports resolution, aligning with the Node.js ESM spec where `PACKAGE_IMPORTS_RESOLVE` does not recursively resolve `#` specifiers. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#503](https://redirect.github.com/webpack/enhanced-resolve/pull/503)) > > Previously `{ "#a": "#b", "#b": "./the.js" }` would chain-resolve `#a` to `./the.js`; now it correctly fails, matching Node.js behavior. > * Move `cachedJoin`/`cachedDirname`/`createCachedBasename` caches from module-level globals to per-Resolver instances. This prevents unbounded memory growth in long-running processes — when a Resolver is garbage collected, its join/dirname/basename caches are released with it. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#507](https://redirect.github.com/webpack/enhanced-resolve/pull/507)) > * Fixed when `tsconfig: true` is used (default config file) and no `tsconfig.json` exists. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#502](https://redirect.github.com/webpack/enhanced-resolve/pull/502)) > * Apply the `extensionAlias` option to the `imports` field to be align with typescript resolution. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#549](https://redirect.github.com/webpack/enhanced-resolve/pull/549)) > * Improved performance of the many plugins. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#529](https://redirect.github.com/webpack/enhanced-resolve/pull/529)) > * Replace the `Set<string>`-based resolver stack with a singly-linked `StackEntry` class that exposes a Set-compatible API. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#526](https://redirect.github.com/webpack/enhanced-resolve/pull/526)) > > Each `doResolve` call now prepends a single linked-list node instead of cloning the entire Set, making stack push O(1) in time and memory. Recursion detection walks the linked list (O(n)), but because the stack is typically shallow this is much cheaper than cloning a Set per call. > * Cache the result of `stripJsonComments` + `JSON.parse` in `readJson` using a `WeakMap` keyed by the raw file buffer. This avoids redundant comment-stripping and JSON parsing on every resolve call that reads tsconfig.json files (via `stripComments: true`), improving TsconfigPathsPlugin warm performance by ~20-35% depending on the depth of the `extends` chain. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#524](https://redirect.github.com/webpack/enhanced-resolve/pull/524)) > * Avoid OOM in CachedInputFileSystem when duration is Infinity. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#527](https://redirect.github.com/webpack/enhanced-resolve/pull/527)) Changelog *Sourced from [enhanced-resolve's changelog](https://github.com/webpack/enhanced-resolve/blob/main/CHANGELOG.md).* > 5.21.0 > ------ > > ### Minor Changes > > * Added promise API and support to resolve without `context` and `resolveContext`. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#520](https://redirect.github.com/webpack/enhanced-resolve/pull/520)) > * Add `extensionAliasForExports` option. When `true`, `extensionAlias` also applies to paths resolved through the `package.json` `exports` field. Off by default to match Node.js; opt in for full TypeScript-resolver parity with packages that ship `.ts` sources alongside the compiled `.js` they declare in `exports`. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#554](https://redirect.github.com/webpack/enhanced-resolve/pull/554)) > > ### Patch Changes > > * Properly handle DOS device paths (`\\?\…` and `\\.\…`). (by [`@alexander-akait`](https://github.com/alexander-akait) in [#551](https://redirect.github.com/webpack/enhanced-resolve/pull/551)) > * Prevent fallback to parent node\_modules when the `exports` field target file is not found. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#495](https://redirect.github.com/webpack/enhanced-resolve/pull/495)) > * Imports field spec deviation: non-relative targets (e.g. `"#a": "#b"`) no longer re-enter imports resolution, aligning with the Node.js ESM spec where `PACKAGE_IMPORTS_RESOLVE` does not recursively resolve `#` specifiers. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#503](https://redirect.github.com/webpack/enhanced-resolve/pull/503)) > > Previously `{ "#a": "#b", "#b": "./the.js" }` would chain-resolve `#a` to `./the.js`; now it correctly fails, matching Node.js behavior. > * Move `cachedJoin`/`cachedDirname`/`createCachedBasename` caches from module-level globals to per-Resolver instances. This prevents unbounded memory growth in long-running processes — when a Resolver is garbage collected, its join/dirname/basename caches are released with it. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#507](https://redirect.github.com/webpack/enhanced-resolve/pull/507)) > * Fixed when `tsconfig: true` is used (default config file) and no `tsconfig.json` exists. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#502](https://redirect.github.com/webpack/enhanced-resolve/pull/502)) > * Apply the `extensionAlias` option to the `imports` field to be align with typescript resolution. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#549](https://redirect.github.com/webpack/enhanced-resolve/pull/549)) > * Improved performance of the many plugins. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#529](https://redirect.github.com/webpack/enhanced-resolve/pull/529)) > * Replace the `Set<string>`-based resolver stack with a singly-linked `StackEntry` class that exposes a Set-compatible API. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#526](https://redirect.github.com/webpack/enhanced-resolve/pull/526)) > > Each `doResolve` call now prepends a single linked-list node instead of cloning the entire Set, making stack push O(1) in time and memory. Recursion detection walks the linked list (O(n)), but because the stack is typically shallow this is much cheaper than cloning a Set per call. > * Cache the result of `stripJsonComments` + `JSON.parse` in `readJson` using a `WeakMap` keyed by the raw file buffer. This avoids redundant comment-stripping and JSON parsing on every resolve call that reads tsconfig.json files (via `stripComments: true`), improving TsconfigPathsPlugin warm performance by ~20-35% depending on the depth of the `extends` chain. (by [`@xiaoxiaojx`](https://github.com/xiaoxiaojx) in [#524](https://redirect.github.com/webpack/enhanced-resolve/pull/524)) > * Avoid OOM in CachedInputFileSystem when duration is Infinity. (by [`@alexander-akait`](https://github.com/alexander-akait) in [#527](https://redirect.github.com/webpack/enhanced-resolve/pull/527)) Commits * [`35035ca`](webpack/enhanced-resolve@35035ca) chore(release): new release ([#496](https://redirect.github.com/webpack/enhanced-resolve/issues/496)) * [`fd688b1`](webpack/enhanced-resolve@fd688b1) perf: cache conditionalMapping + per-plugin description-file lookups ([#556](https://redirect.github.com/webpack/enhanced-resolve/issues/556)) * [`26f15b0`](webpack/enhanced-resolve@26f15b0) fix(path): classify DOS device paths as Windows-absolute ([#551](https://redirect.github.com/webpack/enhanced-resolve/issues/551)) * [`a04bc4c`](webpack/enhanced-resolve@a04bc4c) docs: add resolvePromise examples for Resolver and ResolverFactory ([#555](https://redirect.github.com/webpack/enhanced-resolve/issues/555)) * [`f9f6d57`](webpack/enhanced-resolve@f9f6d57) Merge pull request [#554](https://redirect.github.com/webpack/enhanced-resolve/issues/554) from webpack/claude/fix-extension-alias-alignment-xC6sZ * [`c1319d1`](webpack/enhanced-resolve@c1319d1) chore: regenerate types.d.ts after option rename * [`5a00e63`](webpack/enhanced-resolve@5a00e63) refactor: rename applyExtensionAliasToExportsField to extensionAliasForExports * [`f5adeee`](webpack/enhanced-resolve@f5adeee) test(alias): guard that absolute path aliasing is not skipped ([#553](https://redirect.github.com/webpack/enhanced-resolve/issues/553)) * [`faa178f`](webpack/enhanced-resolve@faa178f) fix(TsconfigPathsPlugin): give references priority over main paths ([#552](https://redirect.github.com/webpack/enhanced-resolve/issues/552)) * [`e82275d`](webpack/enhanced-resolve@e82275d) test(imports/exports): cover query and fragment in field resolution * Additional commits viewable in [compare view](webpack/enhanced-resolve@v5.20.1...v5.21.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security Vulnerability Fix
This pull request fixes a Zip Slip vulnerability either due to an insufficient, or missing guard when unzipping zip files.
Even if you deem, as the maintainer of this project, this is not necessarily fixing a security vulnerability, it is still, most likely, a valid security hardening.
Preamble
Impact
This issue allows a malicious zip file to potentially break out of the expected destination directory, writing contents into arbitrary locations on the file system.
Overwriting certain files/directories could allow an attacker to achieve remote code execution on a target system by exploiting this vulnerability.
Why?
The best description of Zip-Slip can be found in the white paper published by Snyk: Zip Slip Vulnerability
But I had a guard in place, why wasn't it sufficient?
If the changes you see are a change to the guard, not the addition of a new guard, this is probably because this code contains a Zip-Slip vulnerability due to a partial path traversal vulnerability.
To demonstrate this vulnerability, consider
"/usr/outnot".startsWith("/usr/out").The check is bypassed although
/outnotis not under the/outdirectory.It's important to understand that the terminating slash may be removed when using various
Stringrepresentations of theFileobject.For example, on Linux,
println(new File("/var"))will print/var, butprintln(new File("/var", "/")will print/var/;however,
println(new File("/var", "/").getCanonicalPath())will print/var.The Fix
Implementing a guard comparing paths with the method
java.nio.files.Path#startsWithwill adequately protect against this vulnerability.For example:
file.getCanonicalFile().toPath().startsWith(BASE_DIRECTORY)orfile.getCanonicalFile().toPath().startsWith(BASE_DIRECTORY_FILE.getCanonicalFile().toPath())Other Examples
➡️ Vulnerability Disclosure ⬅️
👋 Vulnerability disclosure is a super important part of the vulnerability handling process and should not be skipped! This may be completely new to you, and that's okay, I'm here to assist!
First question, do we need to perform vulnerability disclosure? It depends!
For partial path traversal, consider if user-supplied input could ever flow to this logic. If user-supplied input could reach this conditional, it's insufficient and, as such, most likely a vulnerability.
Vulnerability Disclosure How-To
You have a few options options to perform vulnerability disclosure. However, I'd like to suggest the following 2 options:
JLLeitschuh Disclosurein the subject of your email so it is not missed.Detecting this and Future Vulnerabilities
You can automatically detect future vulnerabilities like this by enabling the free (for open-source) GitHub Action.
I'm not an employee of GitHub, I'm simply an open-source security researcher.
Source
This contribution was automatically generated with an OpenRewrite refactoring recipe, which was lovingly handcrafted to bring this security fix to your repository.
The source code that generated this PR can be found here:
Zip Slip
Why didn't you disclose privately (ie. coordinated disclosure)?
This PR was automatically generated, in-bulk, and sent to this project as well as many others, all at the same time.
This is technically what is called a "Full Disclosure" in vulnerability disclosure, and I agree it's less than ideal. If GitHub offered a way to create private pull requests to submit pull requests, I'd leverage it, but that infrastructure, sadly, doesn't exist yet.
The problem is that, as an open source software security researcher, I (exactly like open source maintainers), I only have so much time in a day. I'm able to find vulnerabilities impacting hundreds, or sometimes thousands of open source projects with tools like GitHub Code Search and CodeQL. The problem is that my knowledge of vulnerabilities doesn't scale very well.
Individualized vulnerability disclosure takes time and care. It's a long and tedious process, and I have a significant amount of experience with it (I have over 50 CVEs to my name). Even tracking down the reporting channel (email, Jira, etc..) can take time and isn't automatable. Unfortunately, when facing problems of this scale, individual reporting doesn't work well either.
Additionally, if I just spam out emails or issues, I'll just overwhelm already over-taxed maintainers, I don't want to do this either.
By creating a pull request, I am aiming to provide maintainers something highly actionable to actually fix the identified vulnerability; a pull request.
There's a larger discussion on this topic that can be found here: JLLeitschuh/security-research#12
Opting Out
If you'd like to opt out of future automated security vulnerability fixes like this, please consider adding a file called
.github/GH-ROBOTS.txtto your repository with the line:This bot will respect the ROBOTS.txt format for future contributions.
Alternatively, if this project is no longer actively maintained, consider archiving the repository.
CLA Requirements
This section is only relevant if your project requires contributors to sign a Contributor License Agreement (CLA) for external contributions.
It is unlikely that I'll be able to directly sign CLAs. However, all contributed commits are already automatically signed off.
If signing your organization's CLA is a strict-requirement for merging this contribution, please feel free to close this PR.
Sponsorship & Support
This contribution is sponsored by HUMAN Security Inc. and the new Dan Kaminsky Fellowship, a fellowship created to celebrate Dan's memory and legacy by funding open-source work that makes the world a better (and more secure) place.
This PR was generated by Moderne, a free-for-open source SaaS offering that uses format-preserving AST transformations to fix bugs, standardize code style, apply best practices, migrate library versions, and fix common security vulnerabilities at scale.
Tracking
All PR's generated as part of this fix are tracked here: JLLeitschuh/security-research#16