Search: com.ar
4,224 threats
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| High | 8.7 | CVE-2025-47273Prowler: setuptools has a path traversal vulnerability in PackageIndex.download that leads to Arbitrary File Write High8.7GCVE DatabaseCVE-2025-47273 ### Summary A path traversal vulnerability in `PackageIndex` was fixed in setuptools version 78.1.1 ### Details ``` def _download_url(self, url, tmpdir): # Determine download filename # name, _fragment = egg_info_for_url(url) if name: while '..' in name: name = name.replace('..', '.').replace('\\', '_') else: name = "__downloaded__" # default if URL has no path contents if name.endswith('.[egg.zip](http://egg.zip/)'): name = name[:-4] # strip the extra .zip before download --> filename = os.path.join(tmpdir, name) ``` Here: https://github.com/pypa/setuptools/blob/6ead555c5fb29bc57fe6105b1bffc163f56fd558/setuptools/package_index.py#L810C1-L825C88 `os.path.join()` discards the first argument `tmpdir` if the second begins with a slash or drive letter. `name` is derived from a URL without sufficient sanitization. While there is some attempt to sanitize by replacing instances of '..' with '.', it is insufficient. ### Risk Assessment As easy_install and package_index are deprecated, the exploitation surface is reduced. However, it seems this could be exploited in a similar fashion like https://github.com/advisories/GHSA-r9hx-vwmv-q579, and as described by POC 4 in https://github.com/advisories/GHSA-cx63-2mw6-8hw5 report: via malicious URLs present on the pages of a package index. ### Impact An attacker would be allowed to write files to arbitrary locations on the filesystem with the permissions of the process running the Python code, which could escalate to RCE depending on the context. ### References https://huntr.com/bounties/d6362117-ad57-4e83-951f-b8141c6e7ca5 https://github.com/pypa/setuptools/issues/4946 | GCVE Database | |||
| Critical | 9.1 | Critical9.1GCVE DatabaseCVE-2025-43859 ### Impact A leniency in h11's parsing of line terminators in chunked-coding message bodies can lead to request smuggling vulnerabilities under certain conditions. ### Details HTTP/1.1 Chunked-Encoding bodies are formatted as a sequence of "chunks", each of which consists of: - chunk length - `\r\n` - `length` bytes of content - `\r\n` In versions of h11 up to 0.14.0, h11 instead parsed them as: - chunk length - `\r\n` - `length` bytes of content - any two bytes i.e. it did not validate that the trailing `\r\n` bytes were correct, and if you put 2 bytes of garbage there it would be accepted, instead of correctly rejecting the body as malformed. By itself this is harmless. However, suppose you have a proxy or reverse-proxy that tries to analyze HTTP requests, and your proxy has a _different_ bug in parsing Chunked-Encoding, acting as if the format is: - chunk length - `\r\n` - `length` bytes of content - more bytes of content, as many as it takes until you find a `\r\n` For example, [pound](https://github.com/graygnuorg/pound/pull/43) had this bug -- it can happen if an implementer uses a generic "read until end of line" helper to consumes the trailing `\r\n`. In this case, h11 and your proxy may both accept the same stream of bytes, but interpret them differently. For example, consider the following HTTP request(s) (assume all line breaks are `\r\n`): ``` GET /one HTTP/1.1 Host: localhost Transfer-Encoding: chunked 5 AAAAAXX2 45 0 GET /two HTTP/1.1 Host: localhost Transfer-Encoding: chunked 0 ``` Here h11 will interpret it as two requests, one with body `AAAAA45` and one with an empty body, while our hypothetical buggy proxy will interpret it as a single request, with body `AAAAXX20\r\n\r\nGET /two ...`. And any time two HTTP processors both accept the same string of bytes but interpret them differently, you have the conditions for a "request smuggling" attack. For example, if `/two` is a dangerous endpoint and the job of the reverse proxy is to stop requests from getting there, then an attacker could use a bytestream like the above to circumvent this protection. Even worse, if our buggy reverse proxy receives two requests from different users: ``` GET /one HTTP/1.1 Host: localhost Transfer-Encoding: chunked 5 AAAAAXX999 0 ``` ``` GET /two HTTP/1.1 Host: localhost Cookie: SESSION_KEY=abcdef... ``` ...it will consider the first request to be complete and valid, and send both on to the h11-based web server over the same socket. The server will then see the two concatenated requests, and interpret them as _one_ request to `/one` whose body includes `/two`'s session key, potentially allowing one user to steal another's credentials. ### Patches Fixed in h11 0.15.0. ### Workarounds Since exploitation requires the combination of buggy h11 with a buggy (reverse) proxy, fixing either component is sufficient to mitigate this issue. ### Credits Reported by Jeppe Bonde Weikop on 2025-01-09. | GCVE Database | |||
| Medium | 5.3 | Medium5.3GCVE DatabaseCVE-2024-47081 ### Impact Due to a URL parsing issue, Requests releases prior to 2.32.4 may leak .netrc credentials to third parties for specific maliciously-crafted URLs. ### Workarounds For older versions of Requests, use of the .netrc file can be disabled with `trust_env=False` on your Requests Session ([docs](https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env)). ### References https://github.com/psf/requests/pull/6965 https://seclists.org/fulldisclosure/2025/Jun/2 | GCVE Database | |||
| Medium | 4.5 | Medium4.5GCVE DatabaseCVE-2026-22702 ## Impact TOCTOU (Time-of-Check-Time-of-Use) vulnerabilities in `virtualenv` allow local attackers to perform symlink-based attacks on directory creation operations. An attacker with local access can exploit a race condition between directory existence checks and creation to redirect virtualenv's app_data and lock file operations to attacker-controlled locations. **Affected versions:** All versions up to and including 20.36.1 **Affected users:** Any user running `virtualenv` on multi-user systems where untrusted local users have filesystem access to shared temporary directories or where `VIRTUALENV_OVERRIDE_APP_DATA` points to a user-writable location. **Attack scenarios:** - Cache poisoning: Attacker corrupts wheels or Python metadata in the cache - Information disclosure: Attacker reads sensitive cached data or metadata - Lock bypass: Attacker controls lock file semantics to cause concurrent access violations - Denial of service: Lock starvation preventing virtualenv operations ## Patches The vulnerability has been patched by replacing check-then-act patterns with atomic `os.makedirs(..., exist_ok=True)` operations. **Fixed in:** PR #3013 **Versions with the fix:** 20.36.2 and later Users should upgrade to version 20.36.2 or later. ## Workarounds If you cannot upgrade immediately: 1. Ensure `VIRTUALENV_OVERRIDE_APP_DATA` points to a directory owned by the current user with restricted permissions (mode 0700) 2. Avoid running `virtualenv` in shared temporary directories where other users have write access 3. Use separate user accounts for different projects to isolate app_data directories ## References - GitHub PR: https://github.com/pypa/virtualenv/pull/3013 - Vulnerability reported by: @tsigouris007 - CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (TOCTOU) - CWE-59: Improper Link Resolution Before File Access | GCVE Database | |||
| High | 7.1 | EPSS 0.4% | High7.1EPSS 0.4%GCVE DatabaseCVE-2026-59196 ## Summary The hoisted dependency alias issue tracked as GHSA-fr4h-3cph-29xv / CAND-PNPM-059 has been addressed in both pnpm and pacquet. A crafted lockfile alias could be joined directly under a hoisted `node_modules` directory. Traversal aliases could escape that directory, while reserved aliases such as `.bin` or `.pnpm` could overwrite pnpm-owned layout. This patch validates package-name semantics and path containment before graph insertion or filesystem work. ## Security boundary - The TypeScript hoisted graph uses the shared safe join helper at the actual `dep.name` sink. - The helper rejects traversal, absolute, platform-specific, and reserved package names. - Pacquet validates the hoister's `dep.0.name` before adding the graph node or recursing. - Both implementations return `ERR_PNPM_INVALID_DEPENDENCY_NAME`. - Pacquet uses the same dependency-name containment rule at its hoisted graph sink as it uses for direct dependency aliases. ## Exploit replay Before the patch, a traversal alias in a hoisted lockfile imported package files outside the intended install root. With this patch, both pnpm and pacquet reject the alias before graph insertion or filesystem work, and the escaped file is not created. ## Files changed - `fs/symlink-dependency/src/safeJoinModulesDir.ts` provides the TypeScript containment helper. - `installing/deps-restorer/src/lockfileToHoistedDepGraph.ts` validates the parsed dependency name at the hoisted graph sink. - `pacquet/crates/package-manager/src/{hoisted_dep_graph.rs,safe_join_modules_dir.rs}` mirrors that boundary in Rust. - TypeScript and Rust tests cover traversal, reserved aliases, and valid scoped names. ## Commands run ```text $ pnpm --filter @pnpm/fs.symlink-dependency test PASS: 24 tests $ pnpm --filter @pnpm/installing.deps-restorer test test/index.ts PASS: exploit regression and positive install control $ cargo test --locked -p pacquet-package-manager --lib PASS: 426 tests $ cargo fmt --all -- --check PASS ``` ## Validation - TypeScript symlink helper: 24 passed. - TypeScript exploit regression: 1 passed. - TypeScript positive hoisted-install control: 1 passed. - Targeted strict TypeScript compiles: passed. - Targeted ESLint: zero errors. - Pacquet helper tests: 3 passed. - Full pacquet package-manager library suite: 426 passed. - `cargo fmt`, parsed two-document lockfile validation, and `git diff --check`: passed. ## Patch Ready-for-review private PR: https://github.com/pnpm/pnpm-ghsa-fr4h-3cph-29xv/pull/1 GitHub reports the branch as mergeable and has requested review from `zkochan`. GitHub intentionally does not run status checks on temporary private-fork PRs; the commands and outcomes above are the recorded local validation: https://docs.github.com/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability ## Compatibility Valid unscoped and scoped package aliases continue to work. The changeset covers `@pnpm/fs.symlink-dependency`, `@pnpm/installing.deps-restorer`, and `pnpm`; pacquet is updated in the same commit for CLI parity. --- Written by an agent (Codex, GPT-5). | GCVE Database | ||
| High | 7.1 | EPSS 0.4% | CVE-2026-59194pnpm · `patch-remove` could delete project-selected files outside the patches directory High7.1EPSS 0.4%GCVE DatabaseCVE-2026-59194 ## Summary The `patch-remove` deletion-scope issue tracked as GHSA-72r4-9c5j-mj57 / CAND-PNPM-030 has been addressed in pnpm. A crafted patch entry could resolve outside the configured patches directory and cause `pnpm patch-remove` to delete an arbitrary reachable file. This patch validates the configured directory and every resolved target before unlinking anything, then deletes the final directory entry without following it. ## Security boundary - Traversal and absolute paths that resolve outside the configured patches directory are rejected before deletion. - Parent directories are canonicalized before deletion, including the case where a nested symlink points outside and the final outside entry is itself dangling. - The complete batch is validated before any file is removed. - Component-aware predicates accept valid names beginning with `..` while still rejecting parent traversal, Windows drive escapes, and UNC escapes. - Valid files and symlinked patch directories whose canonical targets remain below the lockfile directory continue to work. - A final symlink inside a valid patch directory is unlinked without following its target, including when the target is outside or dangling. ## Exploit replay Before the patch, a workspace `patchedDependencies` path that resolved outside the project caused `pnpm patch-remove` to delete the external sentinel. A second replay used a nested parent symlink and a dangling outside victim: `realpath()` returned `ENOENT`, yet the victim was still removed. With this patch, both paths are rejected and the outside entries remain intact. ## Files changed - `patching/commands/src/isSubdirectory.ts` performs component-aware containment checks. - `patching/commands/src/patchRemove.ts` validates the full batch, canonicalizes parents, and unlinks final entries without following them. - `patching/commands/test/{isSubdirectory,patchRemove}.test.ts` covers traversal, nested symlinks, dangling victims, and valid removals. ## Commands run ```text $ pnpm --filter @pnpm/patching.commands test test/isSubdirectory.test.ts test/patchRemove.test.ts PASS: 11 tests across 2 suites $ pnpm --filter @pnpm/patching.commands run compile PASS $ git diff --check PASS ``` ## Validation - Focused handler and path-predicate suites: 11 passed across 2 suites. - Package-wide ESLint: passed. - Package TypeScript build: passed. - Commit hooks, Commitlint, and `git diff --check`: passed. - The broader integration harness was environment-blocked because it writes outside the available temporary root; focused handler tests used `/private/tmp`. ## Patches `10.34.4`: https://github.com/pnpm/pnpm/commit/352ae489f1b14ffdc19d2c6eacb1b06b098c2ddc `11.7.0`: https://github.com/pnpm/pnpm/commit/612a2e6a7333f2b061f452a21b6e62c1c161747f ## Compatibility Missing patch files remain no-ops. Valid symlinked patch directories continue to work when their canonical target stays inside the lockfile directory, and final symlinks are removed without touching their targets. `patch-remove` is not yet in pacquet's command surface, so no Rust-side parity change is required. ## Remaining risk Portable Node APIs do not expose directory-fd-relative `unlinkat()`. A local attacker who can replace an already validated parent directory before the unlink may still win a time-of-check/time-of-use race. The reproduced repository-controlled traversal and symlink paths do not require that concurrent capability and are blocked by this patch. --- Written by an agent (Codex, GPT-5). | GCVE Database | ||
| Medium | 6.5 | EPSS 0.4% | Medium6.5EPSS 0.4%GCVE Database <details> <summary>Maintainer Action Plan</summary> ## Maintainer Action Plan This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path. - Advisory: `CAND-PNPM-085` / `GHSA-4gxm-v5v7-fqc4` - Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-4gxm-v5v7-fqc4 - Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1 - Shared patch branch: `security/ghsa-batch-2026-06-09` - Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22` - Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec` - Maintainer priority: `appendix` - Component: `pnpm global add/remove bin cleanup` - Patch area: bin name/path segment validation - Affected packages: `npm:pnpm` - CWE IDs: `CWE-22`, `CWE-73` - Conservative CVSS: `6.5` / `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H` - Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory. ### Expected Patched Behavior Reserved, dot, and path-segment bin names are rejected or ignored; global remove leaves `PNPM_HOME` and the sentinel file intact. ### Files And Tests To Review - `bins/resolver/src/index.ts` - `bins/resolver/test/index.ts` - `global/commands/test/globalRemove.test.ts` - `pacquet/crates/cmd-shim/src/bin_resolver.rs` - `pacquet/crates/cmd-shim/src/bin_resolver/tests.rs` - `.changeset/strange-bin-segments.md` ### Focused Validation Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed. - Use the private PR checks plus the patched replay coverage matrix for this candidate. The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-085-patched-result.json`. <!-- maintainer-action:end --> ## Title Reserved manifest bin names can make global package operations delete outside the global bin directory </details> ## Description ### Summary Manifest `bin` object keys such as `""`, `"."`, and `".."` passed pnpm's bin-name guard. When a malicious package was installed globally, later global remove, update, or add-replacement flows could re-derive those names from the installed manifest and pass `path.join(globalBinDir, binName)` to `removeBin`. For `"."` this targets the global bin directory; for `".."` this targets its parent. ### Details The vulnerable dataflow was: - `bins/resolver/src/index.ts` converted manifest `bin` object keys to `binName` and only required URL-safe text or `$`. Empty, dot, dot-dot, and scoped forms such as `@scope/..` were not rejected after scope stripping. - `global/packages/src/scanGlobalPackages.ts` scanned installed global package manifests and returned manifest-derived `bin.name` values. - `global/commands/src/globalRemove.ts`, `global/commands/src/globalUpdate.ts`, and global add replacement logic joined those names to `globalBinDir`. - `bins/remover/src/removeBins.ts` recursively removed the resulting path. Install-time checks did not close the gap: bin target paths were package-root checked, conflict checks looked at the same escaped path but did not reject reserved segments, and bin-link warning paths could leave the package installed for later global operations. ### PoC Run: The script first performs a safe prepatch simulation in a temporary directory: ```text prepatch_reserved_bin_name=.. prepatch_delete_target=/.../cand-pnpm-085.XXXXXX/home prepatch_deleted_global_bin_parent=true ``` It then validates the patched implementation: ```bash ./node_modules/.bin/tsgo --build bins/resolver/tsconfig.json ./node_modules/.bin/tsgo --build global/commands/tsconfig.json ./node_modules/.bin/eslint bins/resolver/src/index.ts bins/resolver/test/index.ts global/commands/test/globalRemove.test.ts cd bins/resolver NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts --runInBand cd global/commands NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/globalRemove.test.ts -t "global remove ignores reserved manifest bin names" --runInBand cargo fmt --manifest-path pacquet/crates/cmd-shim/Cargo.toml --check cargo test --manifest-path pacquet/crates/cmd-shim/Cargo.toml bin_resolver --lib git diff --check -- bins/resolver global/commands/test/globalRemove.test.ts pacquet/crates/cmd-shim .changeset/strange-bin-segments.md pnpm-lock.yaml ``` The patched resolver no longer emits reserved bin names, and the global-remove regression proves the deletion sink receives only `path.join(globalBinDir, "good")`. ### Impact Direct confidentiality impact was not validated for this primitive; the sink is deletion/corruption, | GCVE Database | ||
| High | 8.8 | EPSS 0.3% | CVE-2026-55698pnpm@10 · pnpm: Project env lockfile can short-circuit package-manager resolution and execute lockfile-selected pnpm bytes High8.8EPSS 0.3%GCVE DatabaseCVE-2026-55698 <!-- maintainer-action:start --> ## Maintainer Action Plan This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path. - Advisory: `CAND-PNPM-063` / `GHSA-w466-c33r-3gjp` - Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-w466-c33r-3gjp - Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1 - Shared patch branch: `security/ghsa-batch-2026-06-09` - Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22` - Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec` - Maintainer priority: `start-here` - Component: `pnpm packageManager env lockfile` - Patch area: package-manager env lockfile is re-resolved through trusted registries before execution - Affected packages: `npm:pnpm`, `npm:@pnpm/installing.env-installer` - CWE IDs: `CWE-829`, `CWE-494`, `CWE-345` - Conservative CVSS: `8.8` / `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H` - Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory. ### Expected Patched Behavior Committed env-lockfile package-manager entries are force-refreshed through trusted registries before execution; attacker tarball requests and markers stay at zero. ### Files And Tests To Review - `installing/env-installer/src/resolvePackageManagerIntegrities.ts` - `pnpm/src/switchCliVersion.ts` - `pnpm/src/switchCliVersion.test.ts` - `.changeset/clean-package-manager-registries.md` ### Focused Validation Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed. ```bash ./node_modules/.bin/tsgo --build installing/env-installer/tsconfig.json ./node_modules/.bin/tsgo --build pnpm/tsconfig.json PNPM_REGISTRY_MOCK_PORT=7799 NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../node_modules/.bin/jest src/switchCliVersion.test.ts -t "re-resolved package-manager lockfile" --runInBand PNPM_REGISTRY_MOCK_PORT=7799 NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../node_modules/.bin/jest src/switchCliVersion.test.ts src/syncEnvLockfile.test.ts --runInBand ./node_modules/.bin/eslint installing/env-installer/src/resolvePackageManagerIntegrities.ts pnpm/src/switchCliVersion.ts pnpm/src/switchCliVersion.test.ts git diff --check ``` The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-063-patched-result.json`. <!-- maintainer-action:end --> ### Summary pnpm can persist package-manager bootstrap metadata in the first YAML document of `pnpm-lock.yaml`. Before the patch, direct pnpm execution trusted an already resolved `packageManagerDependencies` entry when the committed env lockfile contained matching `pnpm` and `@pnpm/exe` versions. A malicious repository could therefore commit package-manager lockfile package records and snapshots that bypassed fresh package-manager resolution, then cause pnpm to install and execute bytes selected by that committed lockfile state during automatic version switching. ### Details The vulnerable source-to-sink path was: - `lockfile/fs/src/envLockfile.ts` reads the repository's first YAML lockfile document and validates shape only. - `pnpm/src/main.ts` reaches `switchCliVersion()` when a direct pnpm invocation sees a wanted `pnpm` package manager with `onFail=download`. - `pnpm/src/switchCliVersion.ts` reads the committed env lockfile when package-manager metadata should be persisted. - `installing/env-installer/src/resolvePackageManagerIntegrities.ts` treated `packageManagerDependencies` as resolved when only the `pnpm` and `@pnpm/exe` versions matched. - `engine/pm/commands/src/self-updater/installPnpm.ts` converts env-lockfile `snapshots` and `packages` into the wanted lockfile used by `headlessInstall()`. - `pnpm/src/switchCliVersion.ts` executes the installed `pnpm` binary with `spawn.sync()`. The helper fast path is intentionally still version-based for non-execution callers, so the security boundary is enforced at the execution path: `switchCliVersion()` now re-resolves already present package-manager env-lockfile entries before they can reach `installPnpmToStore()` and `spawn.sync()`. ### PoC Standalone PoC and verification script: The PoC constructs a committed env-lockfile object with matching package-manager dependency versions and attacker-selected package metadata: ```json { "importers": { ".": { "configDependencies": {}, "packageManagerDependencies": { "@pnpm/exe": { "specifier": "9.3.0", "version": "9.3.0" }, "pnpm": { "specifier": "9.3.0", "version": "9.3.0" } } } }, "lockfileVersion": "9.0", "packages": { "/pnpm@9.3. | GCVE Database | ||
| High | 7.5 | EPSS 0.2% | CVE-2026-55697pnpm · Repository-controlled configDependencies can select a pacquet native install engine High7.5EPSS 0.2%GCVE DatabaseCVE-2026-55697 <!-- maintainer-action:start --> ## Maintainer Action Plan This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path. - Advisory: `CAND-PNPM-097` / `GHSA-gj8w-mvpf-x27x` - Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x - Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1 - Shared patch branch: `security/ghsa-batch-2026-06-09` - Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22` - Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec` - Maintainer priority: `start-here` - Component: `pnpm configDependencies / pacquet delegation` - Patch area: pacquet/configDependency lifecycle execution is not used as install engine without trust - Affected packages: `npm:pnpm`, `npm:@pnpm/config.reader`, `npm:@pnpm/installing.commands` - CWE IDs: `CWE-829`, `CWE-78`, `CWE-494` - Conservative CVSS: `7.5` / `CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H` - Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory. ### Expected Patched Behavior config-dependency pacquet install engines are not selected unless the trusted allowlist is set outside the repository; the marker file is not created. ### Files And Tests To Review - `config/reader/src/Config.ts` - `config/reader/src/types.ts` - `config/reader/src/configFileKey.ts` - `config/reader/src/index.ts` - `config/reader/test/index.ts` - `installing/commands/src/installDeps.ts` - `installing/commands/test/runPacquet.ts` - `pnpm/test/install/pacquet.ts` - `.changeset/lucky-config-plugin-pnpmfiles.md` ### Focused Validation Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed. ```bash ./node_modules/.bin/tsgo --build config/reader/tsconfig.json ./node_modules/.bin/tsgo --build installing/commands/tsconfig.json ./node_modules/.bin/tsgo --build pnpm/tsconfig.json NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "config dependency code allowlists|user-level preference settings" --runInBand ./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts git diff --check ``` The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-097-patched-result.json`. <!-- maintainer-action:end --> ### Summary pnpm can install `configDependencies` declared in `pnpm-workspace.yaml` before command dispatch. Before the patch, a repository could declare `pacquet` or `@pnpm/pacquet` as a config dependency and pnpm treated that repository-controlled dependency as an install-engine opt-in. During install, pnpm resolved a platform-specific `@pacquet/<platform>-<arch>/pacquet` binary from `node_modules/.pnpm-config/<packageName>` and spawned it as the developer or CI user. ### Details The vulnerable source-to-sink path was: - `config/reader/src/getOptionsFromRootManifest.ts` copies repository `pnpm-workspace.yaml` `configDependencies` into config. - `pnpm/src/getConfig.ts` installs config dependencies before command dispatch. - `installing/env-installer/src/resolveAndInstallConfigDeps.ts` resolves the repository-declared dependency and its optional platform subdependencies. - `installing/env-installer/src/installConfigDeps.ts` fetches, imports, and symlinks the config dependency tree under `node_modules/.pnpm-config`. - `installing/commands/src/installDeps.ts` selected pacquet delegation whenever `configDependencies` contained `pacquet` or `@pnpm/pacquet`. - `installing/deps-installer/src/install/index.ts` called `opts.runPacquet` from frozen and materialization paths. - `installing/commands/src/runPacquet.ts` resolved `@pacquet/${process.platform}-${process.arch}/pacquet` from the installed config dependency package and executed it with `spawn()`. Exact-version, integrity, and platform filters only proved which bytes package resolution selected; they did not establish that the repository was trusted to choose a native install engine. ### PoC Standalone PoC and verification script: Repository fixture: ```yaml packages: - . configDependencies: pacquet: 0.2.2 ``` Registry package shape: ```json { "name": "pacquet", "version": "0.2.2", "optionalDependencies": { "@pacquet/darwin-arm64": "0.2.2" } } ``` Platfo | GCVE Database | ||
| High | 7.5 | EPSS 0.2% | High7.5EPSS 0.2%GCVE DatabaseCVE-2026-55487 ## Summary Keep build approval for opaque dependency sources byte-exact for GHSA-5wx6-mg75-v57r / CAND-PNPM-123. Merged upstream commit `bf1b731ee6` fixed the original name-only approval bypass by making build policy consume the resolved dependency identity. One collision remained: the generic peer-suffix normalizer also stripped parenthesized text from git, URL, tarball, file, and other opaque locators. Approval for one source string could therefore authorize a different attacker-controlled source whose locator normalized to the same value. ## Security boundary - Registry dependency identities still normalize legitimate peer suffixes and retain patch hashes. - Git, URL, tarball, file, directory, and otherwise opaque identities must match the complete resolved locator byte for byte. - Explicit denials use the same normalization as approvals. - Ignored-build output preserves the exact opaque identity, so the key pnpm asks a user to approve is the key policy later checks. - TypeScript pnpm and pacquet implement the same distinction between registry and opaque identities. ## Exploit replay - With `allowBuilds` approving `foo@https://host/pkg.tgz`, the upstream implementation also accepted `foo@https://host/pkg.tgz(evil)` because both passed through peer-suffix removal. - An independent review found a second Rust-only form: `foo@https://host/pkg@1.0.0(good)` and `foo@https://host/pkg@1.0.0(evil)` collided because the parser selected the final `@` and misclassified the opaque URL as a registry package. - A final review found the same parser hazard in source-only locators ending in a semver-looking tail: approval for `https://host/pkg@1.0.0` could collapse `https://host/pkg@1.0.0(evil)`. - The final patch rejects all three collision forms, applies the same exactness to deny rules, accepts exact opaque keys as positive controls, and continues to accept registry packages approved without their peer suffixes. ## Files changed - `building/policy/src/index.ts` and `building/policy/test/index.ts` normalize only parsed registry identities and retain exact opaque keys. - `pacquet/crates/package-manager/src/build_modules.rs` passes snapshot identities to policy, matches TypeScript package-separator parsing, and preserves opaque locators. - `pacquet/crates/package-manager/src/build_modules/tests.rs` covers exact approval and denial, all three collision forms, ignored-build output, and registry peer compatibility. - `.changeset/quiet-opaque-build-identities.md` records patch releases for `@pnpm/building.policy` and `pnpm`. ## Commands run ```text $ jest building/policy/test/index.ts --runInBand 16 passed $ cargo test -p pacquet-package-manager build_modules::tests -- --nocapture 49 passed $ cargo fmt --all -- --check PASS $ git diff --check 84bb4b1a046f3a659de1c9aab1d45dcf814124ce...HEAD PASS ``` ## Validation - The TypeScript policy suite passed all 16 tests. - The final pacquet build-policy suite passed all 49 tests. - The new Rust regression reproduced the extra-`@` collision before the additive fix and passed afterward. - Exact opaque approval and denial, source-only semver-tail collision rejection, registry peer normalization, and ignored-build reporting all have paired tests. - ESLint passed on the changed TypeScript source and test files. - Rust formatting and diff checks passed; the branch is clean and consists of three focused security commits plus additive merges of upstream through `84bb4b1a046f3a659de1c9aab1d45dcf814124ce`. - The focused TypeScript suite and ESLint ran directly through the installed harness. The isolated project build cannot resolve workspace packages without a local install, and the configured registry gateway returns HTTP 403 while fetching `@pnpm/pacquet@0.11.2`; no candidate-focused test failed. ## Patches `10.34.2`: https://github.com/pnpm/pnpm/commit/14bceb1e0b2a71f4f670774db261feb03f38ec23 `11.5.3`: https://github.com/pnpm/pnpm/commit/bf1b731ee6c0ea98709e671ff0f46bf654480ab8 ## Compatibility Registry package approvals keep their existing form. Opaque dependencies that were approved through a normalized parenthesized variant must now use the exact key shown in pnpm's ignored-build output. This is the intended trust-boundary change; no package-resolution or artifact format changes. ## CI note GitHub intentionally does not run status checks on temporary private-fork pull requests. The complete policy suites, formatting, and diff checks above are the applicable validation: https://docs.github.com/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability --- Written by an agent (Codex, GPT-5). | GCVE Database | ||
| Medium | 6.5 | EPSS 0.4% | CVE-2026-55180pnpm · Repository config can expand victim environment secrets into registry requests before scripts run Medium6.5EPSS 0.4%GCVE DatabaseCVE-2026-55180 <!-- maintainer-action:start --> ## Maintainer Action Plan This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path. - Advisory: `CAND-PNPM-122` / `GHSA-3qhv-2rgh-x77r` - Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-3qhv-2rgh-x77r - Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1 - Shared patch branch: `security/ghsa-batch-2026-06-09` - Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22` - Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec` - Maintainer priority: `start-here` - Component: `pnpm config/env replacement and registry auth` - Patch area: project .npmrc env placeholders are not expanded into registry/auth destinations - Affected packages: `npm:pnpm`, `npm:@pnpm/config.reader`, `rust:pacquet` - CWE IDs: `CWE-201`, `CWE-200`, `CWE-522` - Conservative CVSS: `6.5` / `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N` - Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory. ### Expected Patched Behavior Project `.npmrc` environment placeholders do not expand into registry or auth destinations; the secret is absent from the request URL and auth header. ### Files And Tests To Review - `config/reader/src/loadNpmrcFiles.ts` - `config/reader/src/getOptionsFromRootManifest.ts` - `config/reader/test/index.ts` - `config/reader/test/getOptionsFromRootManifest.test.ts` - `pacquet/crates/config/src/npmrc_auth.rs` - `pacquet/crates/config/src/npmrc_auth/tests.rs` - `pacquet/crates/config/src/workspace_yaml.rs` - `pacquet/crates/config/src/workspace_yaml/tests.rs` - `.changeset/sharp-registry-env-placeholders.md` ### Focused Validation Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed. ```bash ./node_modules/.bin/tsgo --build config/reader/tsconfig.json NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/getOptionsFromRootManifest.test.ts --runInBand NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "project \.npmrc does not expand env variables in registry URLs|project \.npmrc does not expand env variables in scoped registry URLs or URL-scoped keys|project \.npmrc does not expand env variables in auth values|user \.npmrc may expand env variables in registry URLs|drops the placeholder when the env var is unset|substitutes normally when the env var is set|only drops the unresolved placeholder|explicit .*undefined.* fallbacks|pnpm-workspace\.yaml registries do not expand env variables|return a warning when the \.npmrc has an env variable" --runInBand ./node_modules/.bin/eslint config/reader/src/loadNpmrcFiles.ts config/reader/src/getOptionsFromRootManifest.ts config/reader/test/index.ts config/reader/test/getOptionsFromRootManifest.test.ts cargo fmt --manifest-path pacquet/crates/config/Cargo.toml --check cargo test --manifest-path pacquet/crates/config/Cargo.toml project_ini_ignores_env_placeholders_in_registry_urls --lib cargo test --manifest-path pacquet/crates/config/Cargo.toml project_ini_ignores_env_placeholders_in_scoped_registry_urls --lib cargo test --manifest-path pacquet/crates/config/Cargo.toml project_ini_ignores_env_placeholders_in_url_scoped_keys --lib cargo test --manifest-path pacquet/crates/config/Cargo.toml project_ini_ignores_env_placeholders_in_auth_values --lib cargo test --manifest-path pacquet/crates/config/Cargo.toml trusted_ini_expands_env_placeholders_in_registry_urls --lib cargo test --manifest-path pacquet/crates/config/Cargo.toml ignores_env_vars_inside_workspace_registry_values --lib git diff --check cargo fmt --check ``` The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-122-patched-result.json`. <!-- maintainer-action:end --> # CAND-PNPM-122: Repository config can expand victim environment secrets into registry requests before scripts run ## Advisory Details ### Summary pnpm and pacquet expanded `${ENV_VAR}` placeholders from repository-controlled `.npmrc` and `pnpm-workspace.yaml` into registry request destinations and registry credentials. A malicious repository could cause dependency resolution to send victim environment secrets to an attacker-selected registry before lifecycle scripts run. ### Details The vulnerable TypeScript pnpm path was: - `config/reader/src/loadNpmrcFiles.ts` loaded project `.npmrc` and substituted environment placeholders in keys and values. - `config/reader/src/getOptionsFromRootManifest.ts` substituted environment placeholders inside workspace `registry`, `regis | GCVE Database | ||
| Medium | 6.8 | EPSS 0.2% | Medium6.8EPSS 0.2%GCVE DatabaseCVE-2026-50021 ## Summary pnpm's tarball extraction worker skips integrity verification when the `integrity` field is absent from the lockfile resolution. If an attacker can both modify `pnpm-lock.yaml` to remove the `integrity:` field and cause the referenced registry URL to serve altered package content, `pnpm install --frozen-lockfile` can install the altered package without an integrity error. npm's `npm ci` enforces integrity by default; pnpm's behavior of silently skipping verification is a pnpm-specific fail-open gap. ## Vulnerability Details The `addTarballToStore` function in `worker/src/start.ts` (lines 189-204) checks `if (integrity)` before verifying the tarball hash. The `TarballResolution` type declares `integrity` as optional (`integrity?: string`). When the lockfile omits the `integrity` field, the guard evaluates to `false`, skipping hash verification entirely. The worker then computes a new hash from the unverified content and stores it as legitimate. ```typescript // worker/src/start.ts:189-204 function addTarballToStore ({ buffer, storeDir, integrity, ... }: TarballExtractMessage) { if (integrity) { // false when integrity is undefined const { algorithm, hexDigest } = parseIntegrity(integrity) const calculatedHash = crypto.hash(algorithm, buffer, 'hex') if (calculatedHash !== hexDigest) { return { status: 'error', error: { type: 'integrity_validation_failed', ... } } } } return { status: 'success', value: { integrity: integrity ?? calcIntegrity(buffer) }, } } ``` ## Proof of Concept ```bash bash autofyn_audit/exploits/vuln1_integrity_bypass/exploit.sh # Publishes a package, generates lockfile, republishes tampered version, # strips integrity field, re-runs install --frozen-lockfile. # Result: PASS -- tampered package installed without integrity error. ``` ## Impact Supply chain compromise in environments where an attacker can both alter the lockfile and cause the referenced registry URL to serve altered package content. The `--frozen-lockfile` flag does not fail closed when the integrity field is missing. ## Suggested Remediation Require an `integrity` field for remote tarball resolutions. Change the `if (integrity)` guard to fail when integrity is absent for non-local packages. When `--frozen-lockfile` is active, reject lockfile entries that lack integrity for remote packages. --- > Discovered by [AutoFyn](https://github.com/SignalPilot-Labs/AutoFyn) > Full audit report: [audit_report.md](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/audit_report.md) > Exploit script: [exploit.sh](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/exploits/vuln1_integrity_bypass/exploit.sh) | GCVE Database | ||
| High | 7.3 | EPSS 0.4% | CVE-2026-50015Pnpm@10 · pnpm Vulnerable to Arbitrary File Write/Delete via Malicious Patch File (Path Traversal) High7.3EPSS 0.4%GCVE DatabaseCVE-2026-50015 ## Summary pnpm's patch application pipeline (`@pnpm/patch-package`) performs no path validation on file paths extracted from `.patch` files. An attacker who contributes a malicious patch file via a pull request can write attacker-controlled content to or delete arbitrary files on the filesystem during `pnpm install`, as the user running the install. The `diff --git` header paths containing `../../` sequences traverse out of the package directory, and the traversal is difficult to catch in code review because patch file diff headers are opaque to most reviewers. ## Vulnerability Details During `pnpm install`, when a `patchedDependencies` entry is present in `pnpm-workspace.yaml`, pnpm reads the referenced `.patch` file and applies it via the embedded `@pnpm/patch-package` library. The `applyPatchToDir` function at `patching/apply-patch/src/index.ts:12-13` calls `process.chdir(opts.patchedDir)`, setting the working directory to the installed package location deep inside `node_modules/.pnpm/`. The patch parser at `@pnpm/patch-package/dist/patch/parse.js:88` extracts file paths from `diff --git a/(.*?) b/(.*?)` headers using a regex with no path sanitization. The `executeEffects` function in `apply.js` then operates on these unsanitized paths: **File write** (`apply.js:35-49`): ```javascript case 'file creation': { const eff = effect fs.ensureDirSync(dirname(eff.path)) fs.writeFileSync(eff.path, fileContents, { mode: eff.mode }) break } ``` **File delete** (`apply.js:13-22`): ```javascript case 'file deletion': { const eff = effect // TODO: integrity checks if (!opts.dryRun) { fs.unlinkSync(eff.path) } break } ``` A path like `../../../../../../../../../../home/user/.ssh/authorized_keys` in the patch header traverses out of the package directory to an arbitrary location. ## Proof of Concept ```bash # Write variant: bash autofyn_audit/exploits/vuln6_patch_traversal_write/exploit.sh # Result: PASS -- /tmp/vuln6_pwned created with attacker-controlled content # Delete variant: bash autofyn_audit/exploits/vuln7_patch_traversal_delete/exploit.sh # Result: PASS -- /tmp/vuln7_target deleted by malicious patch # Combined chain (delete + replace SSH authorized_keys): bash autofyn_audit/exploits/chain2_patch_ssh_backdoor/exploit.sh # Result: PASS -- authorized_keys replaced with attacker's public key ``` ## Impact Arbitrary file write and delete as the user running `pnpm install`, limited to paths writable by that user. An attacker who submits a PR adding a `.patch` file and `patchedDependencies` config can target SSH authorized_keys, shell configuration, CI/CD files, or other writable files. Patch files may receive less review scrutiny than `package.json` changes because the `../` traversal sequences are in `diff --git` headers that look like patch metadata. ## Suggested Remediation Validate parsed patch file paths against the package root directory. Reject any path that resolves outside the patched package directory via `path.resolve` + prefix check. Alternatively, sanitize at parse time by rejecting paths containing `..` components in `parse.js`. --- > Discovered by [AutoFyn](https://github.com/SignalPilot-Labs/AutoFyn) > Full audit report: [audit_report.md](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/audit_report.md) > Exploit script: [exploit.sh](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/exploits/vuln6_patch_traversal_write/exploit.sh) | GCVE Database | ||
| Medium | 6.4 | EPSS 0.3% | Medium6.4EPSS 0.3%GCVE DatabaseCVE-2026-50014 ## Summary pnpm passes the lockfile-controlled git `resolution.commit` value to `git fetch` without a `--` separator or commit-format validation. For git dependencies fetched through the shallow-fetch path, a malicious lockfile can replace the expected 40-character commit hash with a Git option such as `--upload-pack=<command>`. For SSH and local transports, `--upload-pack` can execute the supplied command. HTTPS transports ignore `--upload-pack`, so the practical attack surface is primarily SSH or local git dependencies. ## Vulnerability Details The vulnerable path is in `fetching/git-fetcher/src/index.ts`. When a git dependency host is configured for shallow fetching, pnpm calls: ```typescript await execGit(['fetch', '--depth', '1', 'origin', resolution.commit], { cwd: tempLocation }) ``` Because `resolution.commit` is appended before a `--` separator, Git can parse a commit value beginning with `-` as an option. The same file later passes the value to `git checkout` without a separator: ```typescript await execGit(['checkout', resolution.commit], { cwd: tempLocation }) ``` `resolution.commit` comes from the lockfile and is typed as a plain `string`; pnpm does not validate it as a 40-character hexadecimal commit before passing it to Git. ## Proof of Concept ```bash bash autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh # Creates a local bare git repo and triggers the shallow-fetch path. # Replaces the lockfile commit hash with '--upload-pack=touch /tmp/vuln11_pwned'. # Result: PASS -- /tmp/vuln11_pwned created by injected touch command. ``` The PoC uses a local `file://githost/...` repository because the injection requires a local or SSH transport. HTTPS transport ignores `--upload-pack`. ## Impact Code execution as the user running `pnpm install`, under specific transport conditions. The attacker must modify `pnpm-lock.yaml`, and the affected dependency must use SSH or local git transport. HTTPS transport (the common case) is immune. ## Suggested Remediation Add a `--` separator before lockfile-controlled git revision values. Validate `resolution.commit` matches `/^[0-9a-f]{40}$/i` before passing to Git. --- > Discovered by [AutoFyn](https://github.com/SignalPilot-Labs/AutoFyn) > Full audit report: [audit_report.md](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/audit_report.md) > Exploit script: [exploit.sh](https://github.com/tempcollab/pnpm/blob/main/autofyn_audit/exploits/vuln11_git_upload_pack_rce/exploit.sh) | GCVE Database | ||
| High | 7.5 | EPSS 0.2% | High7.5EPSS 0.2%GCVE DatabaseCVE-2026-48995 ### Summary A malicious `codeload.github.com` server can serve whatever tarball it wants and pnpm will install it regardless of the lockfile. ### Details The lockfile does not store the hash of the dependencies from https://codeload.github.com This means that if this server was compromised or a person's machine configuration was compromised, pnpm would download and install these dependencies. ### PoC ```sh > pnpm -v 10.28.2 ``` Given the following package.json: ```json { "dependencies": { "add": "git://github.com/dsherret/npm-git-dep.git#b3eeb9b" } } ``` This produces a lockfile like so: ```yaml lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: .: dependencies: add: specifier: git://github.com/dsherret/npm-git-dep.git#b3eeb9b version: https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b packages: add@https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b: resolution: {tarball: https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b} version: 1.0.0 snapshots: add@https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b: {} ``` Notice that there is no hash. The `b3eeb9b` is not sufficient because I can configure my machine to resolve a compromised tarball from that url (I tested it out and pnpm just installs it). ### Impact Anyone relying on github git dependencies. | GCVE Database | ||
| Medium | 5.3 | CVE-2026-22701Pip audit · filelock Time-of-Check-Time-of-Use (TOCTOU) Symlink Vulnerability in SoftFileLock Medium5.3GCVE DatabaseCVE-2026-22701 ## Vulnerability Summary **Title:** Time-of-Check-Time-of-Use (TOCTOU) Symlink Vulnerability in SoftFileLock **Affected Component:** `filelock` package - `SoftFileLock` class **File:** `src/filelock/_soft.py` lines 17-27 **CWE:** CWE-362, CWE-367, CWE-59 --- ## Description A TOCTOU race condition vulnerability exists in the `SoftFileLock` implementation of the filelock package. An attacker with local filesystem access and permission to create symlinks can exploit a race condition between the permission validation and file creation to cause lock operations to fail or behave unexpectedly. The vulnerability occurs in the `_acquire()` method between `raise_on_not_writable_file()` (permission check) and `os.open()` (file creation). During this race window, an attacker can create a symlink at the lock file path, potentially causing the lock to operate on an unintended target file or leading to denial of service. ### Attack Scenario ``` 1. Lock attempts to acquire on /tmp/app.lock 2. Permission validation passes 3. [RACE WINDOW] - Attacker creates: ln -s /tmp/important.txt /tmp/app.lock 4. os.open() tries to create lock file 5. Lock operates on attacker-controlled target file or fails ``` --- ## Impact _What kind of vulnerability is it? Who is impacted?_ This is a **Time-of-Check-Time-of-Use (TOCTOU) race condition vulnerability** affecting any application using `SoftFileLock` for inter-process synchronization. **Affected Users:** - Applications using `filelock.SoftFileLock` directly - Applications using the fallback `FileLock` on systems without `fcntl` support (e.g., GraalPy) **Consequences:** - **Silent lock acquisition failure** - applications may not detect that exclusive resource access is not guaranteed - **Denial of Service** - attacker can prevent lock file creation by maintaining symlink - **Resource serialization failures** - multiple processes may acquire "locks" simultaneously - **Unintended file operations** - lock could operate on attacker-controlled files **CVSS v4.0 Score:** 5.6 (Medium) **Vector:** CVSS:4.0/AV:L/AT:L/PR:L/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N **Attack Requirements:** - Local filesystem access to the directory containing lock files - Permission to create symlinks (standard for regular unprivileged users on Unix/Linux) - Ability to time the symlink creation during the narrow race window --- ## Patches _Has the problem been patched? What versions should users upgrade to?_ Yes, the vulnerability has been patched by adding the `O_NOFOLLOW` flag to prevent symlink following during lock file creation. **Patched Version:** Next release (commit: 255ed068bc85d1ef406e50a135e1459170dd1bf0) **Mitigation Details:** - The `O_NOFOLLOW` flag is added conditionally and gracefully degrades on platforms without support - On platforms with `O_NOFOLLOW` support (most modern systems): symlink attacks are completely prevented - On platforms without `O_NOFOLLOW` (e.g., GraalPy): TOCTOU window remains but is documented **Users should:** - Upgrade to the patched version when available - For critical deployments, consider using `UnixFileLock` or `WindowsFileLock` instead of the fallback `SoftFileLock` --- ## Workarounds _Is there a way for users to fix or remediate the vulnerability without upgrading?_ For users unable to update immediately: 1. **Avoid `SoftFileLock` in security-sensitive contexts** - use `UnixFileLock` or `WindowsFileLock` when available (these were already patched for CVE-2025-68146) 2. **Restrict filesystem permissions** - prevent untrusted users from creating symlinks in lock file directories: ```bash chmod 700 /path/to/lock/directory ``` 3. **Use process isolation** - isolate untrusted code from lock file paths to prevent symlink creation 4. **Monitor lock operations** - implement application-level checks to verify lock acquisitions are successful before proceeding with critical operations --- ## References _Are there any links users can visit to find out more?_ - **Similar Vulnerability:** CVE-2025-68146 (TOCTOU vulnerability in UnixFileLock/WindowsFileLock) - **CWE-362 (Concurrent Execution using Shared Resource):** https://cwe.mitre.org/data/definitions/362.html - **CWE-367 (Time-of-check Time-of-use Race Condition):** https://cwe.mitre.org/data/definitions/367.html - **CWE-59 (Improper Link Resolution Before File Access):** https://cwe.mitre.org/data/definitions/59.html - **O_NOFOLLOW documentation:** https://man7.org/linux/man-pages/man2/open.2.html - **GitHub Repository:** https://github.com/tox-dev/filelock --- **Reported by:** George Tsigourakos (@tsigouris007) | GCVE Database | |||
| Medium | 6.9 | EPSS 0.5% | Medium6.9EPSS 0.5%GCVE DatabaseCVE-2026-59938 ### Impact An attacker who uses this vulnerability can craft a PDF which leads to large memory usage. This requires loading images where the declared size values are much too large compared to the actual data. ### Patches This has been fixed in [pypdf==6.14.0](https://github.com/py-pdf/pypdf/releases/tag/6.14.0). ### Workarounds If you cannot upgrade yet, consider applying the changes from PR [#3888](https://github.com/py-pdf/pypdf/pull/3888). | GCVE Database | ||
| Medium | 6.9 | EPSS 0.6% | Medium6.9EPSS 0.6%GCVE DatabaseCVE-2026-59937 ### Impact An attacker who uses this vulnerability can craft a PDF which leads to long runtimes. This requires cross-reference streams with repeated malformed cross-reference streams. ### Patches This has been fixed in [pypdf==6.14.0](https://github.com/py-pdf/pypdf/releases/tag/6.14.0). ### Workarounds If you cannot upgrade yet, consider applying the changes from PR [#3887](https://github.com/py-pdf/pypdf/pull/3887). | GCVE Database |
Page 42 of 242 · 2 duplicate CVE records merged