logo

Database

Insecure or unset HTTP headers - Strict Transport Security

Need

Enforcement of Strict Transport Security (HSTS) headers

Context

• Usage of Ruby 2.0+ for Ruby programming language version compatibility

• Usage of Ruby for building dynamic and object-oriented applications

• Usage of Rails framework for building web applications

Description

1. Non compliant code

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_headers

  private

  def set_headers
    response.headers['X-XSS-Protection'] = '1; mode=block'...

This code is from a Ruby on Rails application, specifically the `ApplicationController` which is the main controller from which all other controllers in the application inherit. The `before_action :set_headers` line ensures that the `set_headers` method is called before every action in every controller. The `set_headers` method itself is setting several important HTTP security headers. `X-Frame-Options` is set to 'SAMEORIGIN' to prevent clickjacking attacks, by ensuring that the content can only be framed by pages on the same domain. `X-XSS-Protection` is set to '1; mode=block' to enable XSS filtering. If a cross-site scripting attack is detected, rather than sanitizing the page, the browser will prevent rendering of the page. `X-Content-Type-Options` is set to 'nosniff' to prevent the browser from MIME-sniffing a response away from the declared content-type. However, the `Strict-Transport-Security` header is missing. This header is used to enforce secure (HTTP over SSL/TLS) connections to the server. This makes it more difficult for hackers to downgrade the connection to a less secure version. Without this header, even if your site supports HTTPS, a user could potentially end up communicating over an insecure HTTP connection.

2. Steps

• Add the Strict-Transport-Security header to the response headers.

• Set the value of the Strict-Transport-Security header to include the 'max-age' directive with a sufficiently long duration.

• Ensure that the Strict-Transport-Security header is only sent over HTTPS connections.

• Consider including the 'includeSubDomains' directive in the Strict-Transport-Security header if applicable.

3. Secure code example

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_headers

  private

  def set_headers
    response.headers['X-XSS-Protection'] = '1; mode=block'...

The updated code includes the `Strict-Transport-Security` HTTP header in the response headers. This header is a security feature that helps protect the website against man-in-the-middle attacks by enforcing the use of HTTPS. The value of the `Strict-Transport-Security` header has been set to `'max-age=31536000; includeSubDomains'`. This means that the browser should remember for 31536000 seconds (approximately one year) that this site should only be accessed using HTTPS. The `includeSubDomains` directive indicates that this rule applies to all subdomains as well. Please note that the `Strict-Transport-Security` header should only be sent over HTTPS connections. If your application also serves HTTP connections, you should add a condition to only add this header for HTTPS requests. This change helps to mitigate the risk of insecure or unset HTTP headers, enhancing the overall security of the application.