Skip to main content

Insecure or unset HTTP headers - Content-Security-Policy

Need

Implementation of secure and properly configured Content-Security-Policy headers

Context

  • Requirement of Ruby 2.0 or later for running the application
  • Usage of Rails framework for building web applications

Description

Non compliant code

# config/application.rb
module YourApp
class Application < Rails::Application
# other configurations...

config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
'X-Content-Type-Options' => 'nosniff'
# Content-Security-Policy header is missing here
}
end
end

The above code is a typical configuration of a Ruby on Rails application. However, it's missing the Content-Security-Policy HTTP header. This header is used to prevent Cross-Site Scripting (XSS) attacks and other code injection attacks by defining the sources from which the browser is allowed to load resources.

Without this header, or with an insecure configuration, the application is more vulnerable to these types of attacks. For example, an attacker could inject malicious scripts into the application which are then executed by the user's browser.

In the provided code, the Content-Security-Policy header is not included in the default_headers configuration. This means that every response from the server will not include this important security header, leaving the application exposed to potential security threats.

Moreover, even if the Content-Security-Policy header was present but configured with insecure values (for example, allowing scripts to be loaded from any source), the application would still be vulnerable to attacks.

Therefore, it's crucial to not only include the Content-Security-Policy header in server responses, but also to configure it securely by restricting the sources from which resources can be loaded.

Steps

  • Add the Content-Security-Policy header to the default headers configuration in the application.rb file.
  • Define the mandatory security policies for the Content-Security-Policy header.
  • Ensure that the defined security policies do not contain insecure values.

Compliant code

# config/application.rb
module YourApp
class Application < Rails::Application
# other configurations...

config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
'X-Content-Type-Options' => 'nosniff',
'Content-Security-Policy' => "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';"
}
end
end

The above code fixes the vulnerability by adding the Content-Security-Policy header to the default headers configuration in the application.rb file.

The Content-Security-Policy header is used to prevent Cross Site Scripting (XSS) and data injection attacks. It does this by specifying the domains that the browser should consider to be valid sources of executable scripts.

In the provided fix, the Content-Security-Policy is set to only allow resources from the same origin ('self') to be loaded. This is done for various types of resources such as default sources, script sources, connection sources, image sources, and style sources.

This means that only scripts that are located at the same origin as the document are allowed to be executed. Any inline scripts or event-handling HTML attributes are also not executed.

This policy helps to mitigate the risk of XSS attacks by restricting where resources can be loaded from, making it harder for an attacker to inject malicious content.

Please note that the actual Content-Security-Policy should be defined based on the specific needs of your application. The provided policy is a very restrictive one and might not work for all applications. It's recommended to thoroughly test this policy in your application before deploying it to production.

References