Overview: A Critical File Upload Flaw in the AdonisJS Ecosystem
A critical path traversal vulnerability, tracked as CVE-2026-21440, has been disclosed in @adonisjs/bodyparser, a core file-handling package used across AdonisJS web applications. Assigned a CVSS v3.1 score of 9.2, this flaw allows unauthenticated remote attackers to write arbitrary files anywhere on the server filesystem — a primitive that trivially escalates to full remote code execution (RCE). Any AdonisJS application that accepts file uploads and has not yet patched should be treated as actively at risk.
What Is CVE-2026-21440?
CVE-2026-21440 is classified under CWE-22: Improper Limitation of a Pathname to a Restricted Directory, commonly known as path traversal. The vulnerability exists in the MultipartFile.move() method of the @adonisjs/bodyparser package. When a developer calls file.move(destination) without explicitly supplying a sanitized name option, the library falls back to using the client-supplied filename — entirely unvalidated — as the target filename.
Because the implementation uses Node.js's path.join() to construct the final file path, and because the overwrite option defaults to true, an attacker can craft a multipart upload request with a filename such as ../../etc/cron.d/pwned to escape the intended upload directory and write content to arbitrary filesystem locations.
Root Cause Analysis
The vulnerability is straightforward to understand once you see the relevant code path. The core issue is a single missing sanitization step:
When
options?.nameis not provided, the method usesthis.clientName— the raw filename value sent by the HTTP client in the multipart form data — without stripping directory traversal sequences before passing it topath.join().
The result: path.join('/var/www/uploads', '../../etc/cron.d/pwned') resolves cleanly to /etc/cron.d/pwned. With overwrite: true as the default, the file is silently replaced even if it already exists.
Attack Flow and Exploitation
Exploitation requires no authentication, no special privileges, and minimal technical complexity — three factors that all contribute to the high CVSS score. The attack prerequisites are:
- The target application runs a vulnerable version of
@adonisjs/bodyparser(≤ 10.1.1 stable, or 11.0.0-next.1 through 11.0.0-next.5) - A file upload endpoint calls
file.move()without an explicit, sanitizednameoption - The web server process has write permissions to the targeted directory
A minimal exploit is a single curl command:
curl -X POST http://target:3333/upload -F "file=@payload.txt;filename=../../tmp/pwned.txt"
From arbitrary file write, post-exploitation paths include writing a cron job for scheduled command execution, overwriting application configuration files to inject malicious logic, planting SSH authorized keys for persistent access, or replacing application source files directly. In containerized but misconfigured environments, the blast radius can extend to the host if volume mounts are present.
Affected Versions and Patch Status
The following versions of @adonisjs/bodyparser are confirmed vulnerable:
- Stable channel: all versions up to and including 10.1.1
- Next channel: 11.0.0-next.1 through 11.0.0-next.5
Patched releases are available now:
- 10.1.2 — stable patched release
- 11.0.0-next.6 — next channel patched release
The patch was released and the CVE was assigned on January 2, 2026, alongside the publication of security advisory GHSA-gvq6-hvvp-h34h. All affected users should upgrade immediately.
Vulnerable vs. Secure Code Patterns
The difference between a vulnerable and a secure file upload handler is a single options object. Below is the pattern to avoid:
Vulnerable:
await file.move(app.tmpPath())— the library silently uses the attacker-controlledclientNameas the destination filename.
The secure pattern generates a server-side filename, completely ignoring the client-supplied name while preserving only the file extension after validation:
Secure: Generate a
cuid()-based name, validate the extension against an allowlist, and passoverwrite: falseto prevent clobbering existing files.
The key principles at work in the secure pattern are: never trust client-supplied filenames, generate server-side identifiers for stored files, restrict accepted extensions explicitly, and disable overwrites unless your application logic specifically requires them.
Broader Mitigations and Defense-in-Depth
Beyond patching and fixing the code pattern, teams should apply layered defenses to reduce exposure from similar vulnerabilities in the future:
- Upgrade immediately — update
@adonisjs/bodyparserto 10.1.2 or 11.0.0-next.6 - Allowlist file extensions — reject uploads with unexpected or dangerous extensions at the application layer
- Filesystem isolation — run the web server process in a container or under a dedicated low-privilege user with write access scoped only to the upload directory
- Principle of least privilege — the web process should never have write access to
/etc, home directories, or application source paths - Audit file upload handlers — search your codebase for any call to
file.move()that does not supply an explicit, sanitizednameoption - Web Application Firewall rules — add WAF rules to detect multipart filenames containing
../or..\sequences
Detection Guidance
To identify whether your codebase is exposed, search for all invocations of .move( on file objects returned by request.file() or request.files(). Any call where the second argument is absent, or where the name property is not set to a server-generated value, should be treated as vulnerable and corrected immediately. Automated SAST tools that model taint flows from HTTP request inputs through filesystem write calls will flag this pattern if configured for Node.js.
In production logs, look for multipart uploads where the reported filename contains ../, %2e%2e%2f, or null bytes — these are strong indicators of active exploitation attempts.
Conclusion
CVE-2026-21440 is a sobering reminder that insecure defaults in widely-adopted framework libraries can introduce critical vulnerabilities at scale. The @adonisjs/bodyparser flaw requires no sophisticated attack tooling — a single curl command is sufficient to achieve arbitrary file write and, in many realistic configurations, full server compromise. The patch is available, the fix is simple, and the risk of inaction is severe. If your application handles file uploads with AdonisJS, auditing your file.move() calls and upgrading the package should be treated as an emergency priority today.