Wasmtime: WASI hard links bypass wasmtime-wasi's FilePerms for destination
## Summary Wasmtime's WASI filesystem implementation lets a guest with a read-only source file capability overwrite that file by hard-linking it into another preopen that allows file writes. An attacker who can run a WASI guest can bypass `WasiCtxBuilder` per-preopen `FilePerms` and modify host files that were exposed as `FilePerms::READ`. This attack is possible through the wasip1, wasip2, and wasip3 interfaces to the WASI filesystem. This attack is also possible through an indirection of renaming a hardlink into another preopen. ### Details `WasiCtxBuilder::preopened_dir` documents `file_perms` as the maximum permissions usable for files in that preopen. However, hard-link creation and renaming only checked directory mutation for permission, and not whether the file permissions matched. This makes an attack possible where: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overwrite `target` The same attack is possible by way of renaming: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in that same preopen * the `alias` file is renamed into a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overw
- Products
- wasmtime-wasi
- Affected versions
- Not specified
- Fixed versions
- 24.0.11, 36.0.12, 45.0.3, 46.0.1
- CVEs
- CVE-2026-58494
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 30 Oct 2026, 22:38 UTC · Revision 1
Source evidence
Wasmtime: WASI hard links bypass wasmtime-wasi's FilePerms for destination
core-osv · Original sourcePublished 16 Oct 2026, 19:57 UTC
## Summary Wasmtime's WASI filesystem implementation lets a guest with a read-only source file capability overwrite that file by hard-linking it into another preopen that allows file writes. An attacker who can run a WASI guest can bypass `WasiCtxBuilder` per-preopen `FilePerms` and modify host files that were exposed as `FilePerms::READ`. This attack is possible through the wasip1, wasip2, and wasip3 interfaces to the WASI filesystem. This attack is also possible through an indirection of renaming a hardlink into another preopen. ### Details `WasiCtxBuilder::preopened_dir` documents `file_perms` as the maximum permissions usable for files in that preopen. However, hard-link creation and renaming only checked directory mutation for permission, and not whether the file permissions matched. This makes an attack possible where: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overwrite `target` The same attack is possible by way of renaming: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in that same preopen * the `alias` file is renamed into a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overw
osv:GHSA-4ch3-9j33-3pmj
wasmtime-wasi
Fixed versions: 24.0.11
wasmtime-wasi
Fixed versions: 36.0.12
wasmtime-wasi
Fixed versions: 45.0.3
wasmtime-wasi
Fixed versions: 46.0.1
Complete source record
{
"id": "53e833e275487da07ff9344adab20fd1db2b1c605e9d1ab4490238d42933153f",
"url": "https://osv.dev/vulnerability/GHSA-4ch3-9j33-3pmj",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "Wasmtime: WASI hard links bypass wasmtime-wasi's FilePerms for destination",
"summary": "## Summary Wasmtime's WASI filesystem implementation lets a guest with a read-only source file capability overwrite that file by hard-linking it into another preopen that allows file writes. An attacker who can run a WASI guest can bypass `WasiCtxBuilder` per-preopen `FilePerms` and modify host files that were exposed as `FilePerms::READ`. This attack is possible through the wasip1, wasip2, and wasip3 interfaces to the WASI filesystem. This attack is also possible through an indirection of renaming a hardlink into another preopen. ### Details `WasiCtxBuilder::preopened_dir` documents `file_perms` as the maximum permissions usable for files in that preopen. However, hard-link creation and renaming only checked directory mutation for permission, and not whether the file permissions matched. This makes an attack possible where: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overwrite `target` The same attack is possible by way of renaming: * a read-only file `target` exists in a preopen with only FilePerms::READ * a hardlink named `alias`, with destination to the `target`, is created in that same preopen * the `alias` file is renamed into a preopen with FilePerms::READ | FilePerms::WRITE * the attacker opens the file `alias` for writing, in which they can overw",
"evidence": "osv:GHSA-4ch3-9j33-3pmj",
"products": [
{
"name": {
"value": "wasmtime-wasi",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "24.0.11",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
},
{
"name": {
"value": "wasmtime-wasi",
"evidence": "/affected/1/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "36.0.12",
"evidence": "/affected/1/ranges"
}
],
"affected_versions": []
},
{
"name": {
"value": "wasmtime-wasi",
"evidence": "/affected/2/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "45.0.3",
"evidence": "/affected/2/ranges"
}
],
"affected_versions": []
},
{
"name": {
"value": "wasmtime-wasi",
"evidence": "/affected/3/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "46.0.1",
"evidence": "/affected/3/ranges"
}
],
"affected_versions": []
}
],
"severity": "medium",
"structured": {
"id": "GHSA-4ch3-9j33-3pmj",
"aliases": [
"CVE-2026-58494",
"GHSA-4ch3-9j33-3pmj",
"RUSTSEC-2026-0188"
],
"metrics": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N"
}
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "24.0.11"
}
]
}
],
"package": {
"name": "wasmtime-wasi",
"purl": "pkg:cargo/wasmtime-wasi",
"ecosystem": "crates.io"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-4ch3-9j33-3pmj/GHSA-4ch3-9j33-3pmj.json"
}
},
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "25.0.0"
},
{
"fixed": "36.0.12"
}
]
}
],
"package": {
"name": "wasmtime-wasi",
"purl": "pkg:cargo/wasmtime-wasi",
"ecosystem": "crates.io"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-4ch3-9j33-3pmj/GHSA-4ch3-9j33-3pmj.json"
}
},
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "37.0.0"
},
{
"fixed": "45.0.3"
}
]
}
],
"package": {
"name": "wasmtime-wasi",
"purl": "pkg:cargo/wasmtime-wasi",
"ecosystem": "crates.io"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-4ch3-9j33-3pmj/GHSA-4ch3-9j33-3pmj.json"
}
},
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "46.0.0"
},
{
"fixed": "46.0.1"
}
]
}
],
"package": {
"name": "wasmtime-wasi",
"purl": "pkg:cargo/wasmtime-wasi",
"ecosystem": "crates.io"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-4ch3-9j33-3pmj/GHSA-4ch3-9j33-3pmj.json"
}
}
],
"modified": "2026-10-16T20:15:03.597563841Z",
"provider": "osv",
"references": [
"https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-4ch3-9j33-3pmj",
"https://nvd.nist.gov/vuln/detail/CVE-2026-58494",
"https://github.com/bytecodealliance/wasmtime/pull/13725",
"https://github.com/bytecodealliance/wasmtime/commit/5ddfd5f1ef28f2041fa07d237ad0336e167b0e0c",
"https://github.com/bytecodealliance/wasmtime/commit/7db94cdcf0c79cb3dfde884b534b653f2dd83367",
"https://github.com/bytecodealliance/wasmtime/commit/8a250aac0962ca1364b5f16525720e9d0b39edcd",
"https://github.com/bytecodealliance/wasmtime/commit/d3ceb56ec35f39e02496eeb4e2d9c7f4fb964d9e",
"https://github.com/bytecodealliance/wasmtime",
"https://github.com/bytecodealliance/wasmtime/releases/tag/v24.0.11",
"https://github.com/bytecodealliance/wasmtime/releases/tag/v36.0.12",
"https://github.com/bytecodealliance/wasmtime/releases/tag/v45.0.3",
"https://github.com/bytecodealliance/wasmtime/releases/tag/v46.0.1",
"https://rustsec.org/advisories/RUSTSEC-2026-0188.html"
],
"provider_metadata": {
"cwe_ids": [
"CWE-281",
"CWE-863"
],
"severity": "MODERATE",
"github_reviewed": true,
"nvd_published_at": "2026-07-08T21:16:54Z",
"github_reviewed_at": "2026-10-16T19:57:26Z"
}
},
"related_cves": [
{
"value": "CVE-2026-58494",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/severity/0/score"
},
"source_id": "core-osv",
"document_id": 347718,
"published_at": "2026-10-16T19:57:26+00:00"
}