Lack of data validation - Host Header Injection
Need
Implementation of strict input validation and sanitization to prevent Host Header Injection
Context
- Requirement of Node.js v14.0.0 or higher for running the application
- Usage of Express for building web applications and APIs
Description
Non compliant code
import express from 'express';
const app = express();
app.get('/', (req, res) => {
const host = req.headers.host;
res.redirect(`http://${host}`);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in this code is a lack of data validation, specifically a Host Header Injection vulnerability.
In the vulnerable code, the application uses the Express framework to create a server. It defines a route for the root URL ("/") using the app.get()
method.
Within the route handler, the code retrieves the value of the host
header from the request using req.headers.host
. The host
header contains the domain name of the requested URL.
The code then uses the retrieved host
value to construct a redirect URL using the res.redirect()
method. The redirect URL is constructed by concatenating the host
value with the "http://" protocol prefix.
The vulnerability lies in the fact that the code does not validate or sanitize the host
value before using it in the redirect URL. This allows an attacker to manipulate the host
header and potentially redirect the user to a malicious website.
For example, an attacker could send a request with a manipulated host
header containing a malicious domain name. The code would then construct a redirect URL using the manipulated domain, leading the user to be redirected to the attacker's website.
To mitigate this vulnerability, it is recommended to validate the host
header against a whitelist of trusted domains. This ensures that only trusted domains are used in the redirect URL and prevents the possibility of unintended redirects to malicious websites.
Steps
- Create a whitelist of trusted domains
- Validate the host header against the whitelist
- If the host is not in the whitelist, handle the request appropriately (e.g., return an error response)
- Update the code to use the validated host header in the redirect URL
Compliant code
import express from 'express';
const app = express();
const trustedDomains = ['example.com', 'trusteddomain.com'];
app.get('/', (req, res) => {
const host = req.headers.host;
if (!trustedDomains.includes(host)) {
return res.status(400).send('Invalid host');
}
res.redirect(`http://${host}`);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability by implementing data validation on the host header.
First, the code imports the Express framework and creates an instance of the application.
A constant named trustedDomains
is defined, which contains a whitelist of trusted domains. This whitelist should include only the domains that are considered safe and allowed for redirection.
The code sets up a route for the root path ("/") using the app.get()
method. Inside the route handler function, the code retrieves the value of the host header from the request object using req.headers.host
.
To validate the host header, the code checks if the host
value is present in the trustedDomains
array using the includes()
method. If the host is not found in the whitelist, the code sends a response with a status code of 400 (Bad Request) and a message indicating that the host is invalid.
If the host is found in the whitelist, the code proceeds to redirect the user to the specified host using the res.redirect()
method. The redirection is done by constructing a new URL with the http://
protocol and the validated host value.
Finally, the code starts the server on port 3000 using the app.listen()
method and logs a message to indicate that the server is running.
By validating the host header against a whitelist of trusted domains, the fixed code ensures that only safe and intended redirects are allowed, preventing the user from being redirected to malicious websites.