CVE-2026-21440
Description
AdonisJS is a TypeScript-first web framework. A Path Traversal vulnerability in AdonisJS multipart file handling may allow a remote attacker to write arbitrary files to arbitrary locations on the server filesystem. This impacts @adonisjs/bodyparser through version 10.1.1 and 11.x prerelease versions prior to 11.0.0-next.6. This issue has been patched in @adonisjs/bodyparser versions 10.1.2 and 11.0.0-next.6.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@adonisjs/bodyparsernpm | < 10.1.2 | 10.1.2 |
@adonisjs/bodyparsernpm | >= 11.0.0-next.0, < 11.0.0-next.6 | 11.0.0-next.6 |
Affected products
1- Range: 2.0.5, v1.0.0, v1.0.1, …
Patches
26795c0e3fa82fix: path traversal during file.move operation
2 files changed · +13 −5
src/multipart/file.ts+5 −1 modified@@ -8,6 +8,7 @@ */ import { join } from 'node:path' +import crypto from 'node:crypto' import { Exception } from '@poppinss/utils' import Macroable from '@poppinss/macroable' @@ -181,7 +182,10 @@ export class MultipartFile extends Macroable { }) } - options = Object.assign({ name: this.clientName, overwrite: true }, options) + options = Object.assign( + { name: `${crypto.randomUUID()}.${this.extname ?? 'unknown'}`, overwrite: true }, + options + ) const filePath = join(location, options.name!) try {
tests/body_parser.spec.ts+8 −4 modified@@ -24,7 +24,7 @@ import { import { AppFactory } from '@adonisjs/application/factories' import { Multipart } from '../src/multipart/main.js' -import { MultipartFile } from '../src/multipart/file.js' +import { type MultipartFile } from '../src/multipart/file.js' import { BodyParserMiddlewareFactory } from '../factories/middleware_factory.js' import { packageFilePath, packageFileSize, unicornFilePath } from '../tests_helpers/main.js' @@ -998,6 +998,7 @@ test.group('BodyParser Middleware | multipart', () => { await pkgFile.move(fs.basePath) assert.equal(pkgFile.state, 'moved') res.writeHead(200, { 'content-type': 'application/json' }) + res.write(JSON.stringify({ file: pkgFile })) res.end() } catch (error) { res.writeHead(500, { 'content-type': 'application/json' }) @@ -1006,9 +1007,12 @@ test.group('BodyParser Middleware | multipart', () => { }) }) - await supertest(server).post('/').attach('package', packageFilePath).expect(200) + const { body } = await supertest(server) + .post('/') + .attach('package', packageFilePath) + .expect(200) - const uploadedFileContents = await fs.contents('package.json') + const uploadedFileContents = await fs.contents(body.file.fileName) const originalFileContents = await readFile(packageFilePath, 'utf-8') assert.equal(uploadedFileContents, originalFileContents) }) @@ -1055,7 +1059,7 @@ test.group('BodyParser Middleware | multipart', () => { const pkgFile = ctx.request.file('package')! try { - await pkgFile.move(fs.basePath, { overwrite: false }) + await pkgFile.move(fs.basePath, { name: 'package.json', overwrite: false }) } catch (error) { assert.equal( error.message,
143a16f35602fix: always generate a random filename when performing move operation
3 files changed · +14 −5
src/bodyparser_middleware.ts+2 −1 modified@@ -8,6 +8,7 @@ */ import { tmpdir } from 'node:os' +import string from '@poppinss/utils/string' import { join, isAbsolute } from 'node:path' import { Exception } from '@poppinss/utils/exception' import type { HttpContext } from '@adonisjs/http-server' @@ -110,7 +111,7 @@ export class BodyParserMiddleware { return isAbsolute(tmpPath) ? tmpPath : join(tmpdir(), tmpPath) } - return join(tmpdir(), crypto.randomUUID()) + return join(tmpdir(), string.uuid()) } /**
src/multipart/file.ts+5 −1 modified@@ -15,6 +15,7 @@ import { moveFile } from '../utils.ts' import { SizeValidator } from './validators/size.ts' import { ExtensionValidator } from './validators/extensions.ts' import type { FileJSON, FileUploadError, FileValidationOptions } from '../types.ts' +import string from '@poppinss/utils/string' /** * The file holds the meta/data for an uploaded file, along with @@ -217,7 +218,10 @@ export class MultipartFile extends Macroable { }) } - options = Object.assign({ name: this.clientName, overwrite: true }, options) + options = Object.assign( + { name: `${string.random(40)}.${this.extname ?? 'unknown'}`, overwrite: true }, + options + ) const filePath = join(location, options.name!) try {
tests/body_parser.spec.ts+7 −3 modified@@ -1070,6 +1070,7 @@ test.group('BodyParser Middleware | multipart', () => { await pkgFile.move(fs.basePath) assert.equal(pkgFile.state, 'moved') res.writeHead(200, { 'content-type': 'application/json' }) + res.write(JSON.stringify({ file: pkgFile })) res.end() } catch (error) { res.writeHead(500, { 'content-type': 'application/json' }) @@ -1078,9 +1079,12 @@ test.group('BodyParser Middleware | multipart', () => { }) }) - await supertest(server).post('/').attach('package', packageFilePath).expect(200) + const { body } = await supertest(server) + .post('/') + .attach('package', packageFilePath) + .expect(200) - const uploadedFileContents = await fs.contents('package.json') + const uploadedFileContents = await fs.contents(body.file.fileName) const originalFileContents = await readFile(packageFilePath, 'utf-8') assert.equal(uploadedFileContents, originalFileContents) }) @@ -1127,7 +1131,7 @@ test.group('BodyParser Middleware | multipart', () => { const pkgFile = ctx.request.file('package')! try { - await pkgFile.move(fs.basePath, { overwrite: false }) + await pkgFile.move(fs.basePath, { name: 'package.json', overwrite: false }) } catch (error) { assert.equal( error.message,
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-gvq6-hvvp-h34hghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-21440ghsaADVISORY
- github.com/adonisjs/bodyparser/commit/143a16f35602be8561215611582211dec280cae6nvdWEB
- github.com/adonisjs/bodyparser/commit/6795c0e3fa824ae275bbd992aae60609e96f0f03nvdWEB
- github.com/adonisjs/bodyparser/releases/tag/v10.1.2nvdWEB
- github.com/adonisjs/bodyparser/releases/tag/v11.0.0-next.6nvdWEB
- github.com/adonisjs/core/security/advisories/GHSA-gvq6-hvvp-h34hnvdWEB
News mentions
0No linked articles in our index yet.