ngx_cache_purge before 3.0.4 can allow file deletion via a symlink attack in certain situations where nginx and a served application (e.g., WordPress) run under the same user account. The attacker must be able to create a symlink inside the cache path. Version 3.0.4 fixes this for the case of a symlink created at an arbitrary earlier time, but does not resolve an applicable TOCTOU race condition. (The ngx_cache_purge module follows symlinks while walking the cache directory tree during purge operations. The module relies on nginx's ngx_walk_tree(), which relies on stat() and therefore follows symlinks.)
{
"cna_assigner": "mitre",
"cwe_ids": [
"CWE-61"
],
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/108xxx/CVE-2026-108981.json"
}{
"extracted_events": [
{
"introduced": "2.4.0"
},
{
"last_affected": "2.5.6"
},
{
"introduced": "3.0.0"
},
{
"fixed": "3.0.4"
}
],
"source": "AFFECTED_FIELD"
}
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-108981.json"
[
{
"deprecated": false,
"digest": {
"function_hash": "42488412667070391216245842232122802585",
"length": 2265
},
"id": "CVE-2026-108981-2c00f24b",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/nginx-modules/ngx_cache_purge/commit/a6da1352f52a8a02dd6828e88c39ed42fddcee96",
"target": {
"file": "ngx_cache_purge_module.c",
"function": "ngx_http_cache_purge_process_queue"
}
},
{
"deprecated": false,
"digest": {
"function_hash": "328403948350427987632494647305588364099",
"length": 941
},
"id": "CVE-2026-108981-2dd401df",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/nginx-modules/ngx_cache_purge/commit/a6da1352f52a8a02dd6828e88c39ed42fddcee96",
"target": {
"file": "ngx_cache_purge_module.c",
"function": "ngx_http_cache_purge_partial"
}
},
{
"deprecated": false,
"digest": {
"function_hash": "9330872102484916337679959276554229163",
"length": 927
},
"id": "CVE-2026-108981-70c047a1",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/nginx-modules/ngx_cache_purge/commit/a6da1352f52a8a02dd6828e88c39ed42fddcee96",
"target": {
"file": "ngx_cache_purge_module.c",
"function": "ngx_http_cache_purge_delete_variants"
}
},
{
"deprecated": false,
"digest": {
"line_hashes": [
"107194538448353258866213937444810481315",
"101369650343922128951182581026400283771",
"122266762876558058731263132037496578588",
"257010542600082173695372802222069866288",
"320087006805668676824254917023551802907",
"155362118351256243110022732175160344493",
"284271028780906753223230919635085158841",
"338481995276693777632208447986139264272",
"74224491209418341854105232316716703612",
"267327508167837079121854874013211589004",
"198774855207003613850056119082558463411",
"338481995276693777632208447986139264272",
"61365270699270435363185948212929120103",
"202664429487734634691507449901141001969",
"102319757036324475369505887790344199840",
"148325552839077597768844376960683208598",
"89049944512741385506565769421639810620",
"159854245962562026317023611625061547675",
"338481995276693777632208447986139264272",
"202673321100523511204211732495177041857",
"336867469324160861631238099384570797922",
"268508444438215165912143213750438920941",
"338481995276693777632208447986139264272"
],
"threshold": 0.9
},
"id": "CVE-2026-108981-91925563",
"signature_type": "Line",
"signature_version": "v1",
"source": "https://github.com/nginx-modules/ngx_cache_purge/commit/a6da1352f52a8a02dd6828e88c39ed42fddcee96",
"target": {
"file": "ngx_cache_purge_module.c"
}
},
{
"deprecated": false,
"digest": {
"function_hash": "118860006365715410049579663643521483018",
"length": 692
},
"id": "CVE-2026-108981-afa382d7",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/nginx-modules/ngx_cache_purge/commit/a6da1352f52a8a02dd6828e88c39ed42fddcee96",
"target": {
"file": "ngx_cache_purge_module.c",
"function": "ngx_http_cache_purge_all"
}
}
]
"2026-10-13T07:01:41Z"