Skip to main content

Insecure or unset HTTP headers - CORS

Need

Enforcement of secure and specific Cross-Origin Resource Sharing (CORS) policies

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of Shelf for managing and organizing data in Node.js applications

Description

Non compliant code

import 'package:shelf/shelf.dart' as shelf;

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.middleware.addHeaders({
// This is the vulnerable part of the code
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
})).addHandler(_echoRequest);

shelf.serve(handler, 'localhost', 8080);
}

shelf.Response _echoRequest(shelf.Request request) {
return shelf.Response.ok('Request for "${request.url}"');
}

In the code above, the server is set to respond to every request with the headers Access-Control-Allow-Origin set to * and Access-Control-Allow-Headers set to 'Origin, X-Requested-With, Content-Type, Accept'.

The Access-Control-Allow-Origin header determines which domains are allowed to access the resources on the server. By setting this to *, the server is allowing any domain to access its resources. This is a security vulnerability as it allows Cross-Origin Resource Sharing (CORS) from any origin, potentially exposing sensitive data to malicious sites.

The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. This header is not directly a security vulnerability, but when combined with a wildcard Access-Control-Allow-Origin, it can contribute to potential security risks.

In conclusion, the vulnerability in the code lies in the indiscriminate use of the wildcard * in the Access-Control-Allow-Origin header, which opens up the server resources to be accessed from any origin.

Steps

  • Identify the specific domains that your application needs to share resources with instead of using a wildcard '*'.
  • Replace the wildcard '*' in the 'Access-Control-Allow-Origin' header with the specific domain(s).
  • If multiple domains need to be allowed, consider implementing a check in your server-side code to match the 'Origin' header of incoming requests against a list of allowed domains.
  • If a match is found, set the 'Access-Control-Allow-Origin' header to the matched domain in the response.
  • Ensure that the 'Access-Control-Allow-Headers' only includes the specific headers that are necessary for your application.

Compliant code

import 'package:shelf/shelf.dart' as shelf;

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.middleware.addHeaders({
// This is the fixed part of the code
'Access-Control-Allow-Origin': 'http://example.com', // replace with your specific domain
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
})).addHandler(_echoRequest);

shelf.serve(handler, 'localhost', 8080);
}

shelf.Response _echoRequest(shelf.Request request) {
return shelf.Response.ok('Request for "${request.url}"');
}

The original code had a vulnerability in the Cross-Origin Resource Sharing (CORS) configuration. The 'Access-Control-Allow-Origin' header was set to '*', which means that any domain can share resources with your application. This can lead to security issues as it allows any website to make a request to your server and read the response.

The fixed code replaces the wildcard '*' in the 'Access-Control-Allow-Origin' header with a specific domain ('http://example.com' in this case). This means that only this specific domain is allowed to share resources with your application.

If your application needs to share resources with multiple domains, you should implement a check in your server-side code to match the 'Origin' header of incoming requests against a list of allowed domains. If a match is found, set the 'Access-Control-Allow-Origin' header to the matched domain in the response.

Also, ensure that the 'Access-Control-Allow-Headers' only includes the specific headers that are necessary for your application. This can help to prevent potential security issues related to header injection.

References