CVE-2026-103061
Path traversal in Gleam via unvalidated package application names
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Active
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
5.9
Path traversal in Gleam via unvalidated package application names
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
- Record
CVE-2026-103061- CVSS 4.0
- 5.9 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-22
- Updated
- 2026-11-02
EUVDEUVD-2026-97758
5.9
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
- Record
EUVD-2026-97758- CVSS 4.0
- 5.9 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
NVD
5.9
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
- Record
CVE-2026-103061- CVSS 4.0
- 5.9 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-22
- Updated
- 2026-11-02
OSV
5.9
Path traversal in Gleam via unvalidated package application names
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
- Record
CVE-2026-103061- CVSS 4.0
- 5.9 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-22
- Updated
- 2026-11-07
OSVEEF-CVE-2026-103061
5.9
Path traversal in Gleam via unvalidated package application names
Summary
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in gleam-lang gleam allows a malicious package publisher to delete a directory outside the project's build directory when a developer builds a project.
A Hex package release's metadata carries an app field with the release's OTP application name. Gleam reads this field from the hex.pm release API when it downloads dependencies and uses it as the package's build directory name without validating it (hex_manifest_package in compiler-cli/src/dependencies.rs, ProjectPaths::build_directory_for_package). When a dependency fails to compile, Gleam deletes that directory with remove_dir_all. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target or an absolute path. When a project depends on such a release directly or transitively and the release fails to compile, gleam build, gleam check, gleam run, gleam test or gleam export deletes the directory the name resolves to. For a pure Gleam package no publisher code runs.
This issue affects gleam: from 0.32.4 before 1.19.2.
Details
hex_manifest_package(compiler-cli/src/dependencies.rs) sets the manifest package'sotp_apptometa.appfromGET packages/<name>/releases/<version>without validation. hex.pm doesn't restrict this field to a directory name. The signed registry record's dependencyapplabel is decoded but never used as a path.ManifestPackage::application_name(compiler-core/src/manifest.rs) returnsotp_appwhen it is set.ProjectPaths::build_directory_for_package(compiler-core/src/paths.rs) joins the application name onto the target's build directory. A..component escapes the build directory, and an absolute path replaces the whole path.- When a dependency fails to compile,
ProjectCompiler::load_cache_or_compile_package(compiler-core/src/build/project_compiler.rs) callsdelete_directoryon that path, which runsstd::fs::remove_dir_all(compiler-cli/src/fs.rs). - The manifest built by
download_dependenciesis passed tobuild::mainin the same run, so the name reaches compilation without amanifest.tomlround trip.otp_appis validated against^[a-z][a-z0-9_]*$only whenmanifest.tomlis read from disk (commit 2dc0467, first released in v1.16.0), which rejects a stored malicious manifest on a later run but not the first run that produces it. - Extraction uses the package name, which hex.pm validates, so the effect is a directory delete without an overwrite. For a package with
build_tools = ["gleam"]no publisher code runs, so source that fails to compile or a malformedgleam.tomltriggers the delete. For rebar3 and Mix dependencies, publisher code runs anyway.
Proof of concept
Not reproduced end to end, because Gleam only uses hex.pm and has no setting for another repository. A unit test calling ProjectPaths::build_directory_for_package with the application names ../../../../canary and an absolute path computed build directories outside the project, and std::fs::remove_dir_all, the call behind delete_directory, deleted a canary directory placed there. The chain from meta.app to the delete was established by reading the source.
Impact
A publisher of a package in a project's dependency tree can make a Gleam build delete a directory that the developer's account can write, outside the project's build directory or anywhere on the filesystem when the application name is an absolute path. For a pure Gleam package this happens without running any of the publisher's code. Developers and CI jobs that build projects with Gleam are affected; gleam deps download alone isn't.
Configurations
Affects projects whose dependency tree, directly or transitively, contains a hex.pm package release whose OTP application name is a path, when the project is built with gleam build, gleam check,…
- Record
EEF-CVE-2026-103061- CVSS 4.0
- 5.9 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12454-1 No score
gleam-1.19.2-1.1 on GA media
These are all security issues fixed in the gleam-1.19.2-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12454-1- Updated
- 2026-11-07
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
gleamopenSUSE:Tumbleweed From an advisory covering 3 CVEs |
before 1.19.2-1.1 | 1.19.2-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, references | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-103061 is a medium vulnerability (CVSS 5.9) in Gleam, published October 12, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.40%, the 34th percentile. No source names a fixed version.
References
github.com/gleam-lang/gleam/security/advisories/GHSA-jhcr-c7qm-8589
cna.erlef.org/cves/CVE-2026-103061.html
osv.dev/vulnerability/EEF-CVE-2026-103061
github.com/gleam-lang/gleam/commit/d13f27ee80aae7a521d2e9433c4deaf53f892574
github.com/gleam-lang/gleam/commit/d15c981fac6e533d70ac8ee89a6ef4dbf139adc3
github.com/gleam-lang/gleam/commit/54bbb2b98af1505b6eed93c45b1936fc76412e5c
Left out here: the rest of 1 source description. The JSON record has them.