logo

Insecure or unset HTTP headers - CORS - Typescript


Need

Enforce secure and specific HTTP headers for Cross-Origin Resource Sharing (CORS)


Context

  1. Usage of TypeScript for type-checking and compiling JavaScript code
  2. Usage of Express for building web applications and APIs

Description

Insecure Code Example

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

  1. Remove the wildcard (*) from the 'Access-Control-Allow-Origin' header and define explicitly the trusted origins for sharing resources.
  2. Remove the wildcard (*) from the 'Access-Control-Allow-Headers' header and define explicitly the allowed headers.
  3. Remove the wildcard (*) from the 'Access-Control-Allow-Methods' header and define explicitly the allowed HTTP methods.
  4. Update the code to handle preflight requests if necessary.
  5. Test the updated code to ensure proper functioning.

Secure Code Example

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.


References

  • 134 - Insecure or unset HTTP headers - CORS

  • Last updated

    2023/09/18