Insecure or unset HTTP headers - CORS
Need
Enforce secure and specific HTTP headers for Cross-Origin Resource Sharing (CORS)
Context
- Usage of TypeScript for type-checking and compiling JavaScript code
- Usage of Express for building web applications and APIs
Description
Non compliant code
import express from 'express';
const app = express();
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
next();
});
app.get('/api/data', (req, res) => {
res.json({ message: 'This is sensitive data!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in this code is related to insecure or unset HTTP headers, specifically the Cross-Origin Resource Sharing (CORS) policy.
In the code, the Access-Control-Allow-Origin
header is set to *
, which means that any domain is allowed to access the resources served by this application. This wildcard configuration can be exploited by attackers to include resources from untrusted origins, potentially leading to cross-site scripting (XSS) attacks or data leakage.
Additionally, the Access-Control-Allow-Headers
and Access-Control-Allow-Methods
headers are also set to *
, allowing any headers and methods to be used in cross-origin requests. This can further increase the attack surface and potential security risks.
To address this vulnerability, it is recommended to remove the wildcard (*) and explicitly define the trusted origins for accessing the application resources. This ensures that only specified domains are allowed to make cross-origin requests.
Steps
- Remove the wildcard (*) from the 'Access-Control-Allow-Origin' header and define explicitly the trusted origins for sharing resources.
- Remove the wildcard (*) from the 'Access-Control-Allow-Headers' header and define explicitly the allowed headers.
- Remove the wildcard (*) from the 'Access-Control-Allow-Methods' header and define explicitly the allowed HTTP methods.
- Update the code to handle preflight requests if necessary.
- Test the updated code to ensure proper functioning.
Compliant code
import express from 'express';
const app = express();
const allowedOrigins = ['https://trusted-domain1.com', 'https://trusted-domain2.com'];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
next();
});
app.get('/api/data', (req, res) => {
res.json({ message: 'This is sensitive data!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability by implementing proper Cross-Origin Resource Sharing (CORS) policies.
First, the code imports the Express framework and creates an instance of the application.
Next, an array called allowedOrigins
is defined, which contains the trusted domains that are allowed to access the application's resources.
The code then sets up a middleware function using app.use()
that will be executed for every incoming request. This middleware function checks the origin
header of the request to determine the domain from which the request originated.
If the origin
is found in the allowedOrigins
array, the code sets the Access-Control-Allow-Origin
header in the response to the value of the origin
header. This allows requests from the trusted domains to access the resources.
Additionally, the code sets the Access-Control-Allow-Headers
header to specify the allowed request headers, and the Access-Control-Allow-Methods
header to specify the allowed HTTP methods.
Finally, the code defines a route for the /api/data
endpoint, which simply responds with a JSON message containing sensitive data.
The application listens on port 3000, and a message is logged to the console indicating that the server is running.
Overall, the fixed code explicitly defines the trusted origins for sharing resources and removes the wildcard (*) that could potentially allow resources to be accessed from untrusted origins.