Why is this an issue?
If the file upload feature is implemented without proper folder restriction, it will result in an implicit trust violation within the server, as
trusted files will be implicitly stored alongside third-party files that should be considered untrusted.
This can allow an attacker to disrupt the security of an internal server process or the running application.
What is the potential impact?
After discovering this vulnerability, attackers may attempt to upload as many different file types as possible, such as javascript files, bash
scripts, malware, or malicious configuration files targeting potential processes.
Below are some real-world scenarios that illustrate the potential impact of an attacker exploiting the vulnerability.
Full application compromise
In the worst-case scenario, the attackers succeed in uploading a file recognized by in an internal tool, triggering code execution.
Depending on the attacker, code execution can be used with different intentions:
- Download the internal server’s data, most likely to sell it.
- Modify data, install malware, for instance, malware that mines cryptocurrencies.
- Stop services or exhaust resources, for instance, with fork bombs.
Server Resource Exhaustion
By repeatedly uploading large files, an attacker can consume excessive server resources, resulting in a denial of service.
If the component affected by this vulnerability is not a bottleneck that acts as a single point of failure (SPOF) within the application, the
denial of service can only affect the attacker who caused it.
Even though a denial of service might have little direct impact, it can have secondary impact in architectures that use containers and container
orchestrators. For example, it can cause unexpected container failures or overuse of resources.
In some cases, it is also possible to force the product to "fail open" when resources are exhausted, which means that some security features are
disabled in an emergency.
These threats are particularly insidious if the attacked organization does not maintain a disaster recovery plan (DRP).
How to fix it in Formidable
Code examples
Noncompliant code example
const Formidable = require('formidable');
const form = new Formidable(); // Noncompliant
form.uploadDir = "/tmp/";
form.keepExtensions = true;
Compliant solution
const Formidable = require('formidable');
const form = new Formidable();
form.uploadDir = "/uploads/";
form.keepExtensions = false;
How does this work?
Use pre-approved folders
Create a special folder where untrusted data should be stored. This folder should be classified as untrusted and have the following
characteristics:
- It should have specific read and write permissions that belong to the right people or organizations.
- It should have a size limit or its size should be monitored.
- It should contain backup copies if it contains data that belongs to users.
This folder should not be located in /tmp
, /var/tmp
or in the Windows directory %TEMP%
.
These folders
are usually "world-writable", can be manipulated, and can be accidentally deleted by the system.
Also, the original file names and extensions should be changed to controlled strings to prevent unwanted code from being executed based on the file
names.
How to fix it in Multer
Code examples
Noncompliant code example
The following code sample is vulnerable because it implicitly uses /tmp
or /var/tmp
as upload directory.
const crypto = require('node:crypto');
const multer = require('multer');
let diskStorage = multer.diskStorage({
filename: (req, file, cb) => {
const buf = crypto.randomBytes(20);
cb(null, buf.toString('hex'))
}
}); // Noncompliant
let diskUpload = multer({
storage: diskStorage,
});
Compliant code example
const multer = require('multer');
let diskStorage = multer.diskStorage({
filename: (req, file, cb) => {
const buf = crypto.randomBytes(20);
cb(null, buf.toString('hex'))
},
destination: (req, file, cb) => {
cb(null, '/uploads/')
}
});
let diskUpload = multer({
storage: diskStorage,
});
How does this work?
Use pre-approved folders
Create a special folder where untrusted data should be stored. This folder should be classified as untrusted and have the following
characteristics:
- It should have specific read and write permissions that belong to the right people or organizations.
- It should have a size limit or its size should be monitored.
- It should contain backup copies if it contains data that belongs to users.
This folder should not be located in /tmp
, /var/tmp
or in the Windows directory %TEMP%
.
These folders
are usually "world-writable", can be manipulated, and can be accidentally deleted by the system.
Also, the original file names and extensions should be changed to controlled strings to prevent unwanted code from being executed based on the file
names.
Resources