logo

Insecure or unset HTTP headers - X-Frame Options - Ruby


Need

Implementation of secure and properly configured HTTP headers


Context

  1. Usage of Ruby 2.0+ for developing Ruby applications
  2. Usage of Rails for building web applications in Ruby

Description

Insecure Code Example

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

  private

  def set_headers
    response.headers["X-Frame-Options"] = "SAMEORIGIN"
  end
end

In the above code, the application sets the `X-Frame-Options` HTTP header to `SAMEORIGIN` in every response from the server. This is done in the `ApplicationController`, which is the superclass of all other controllers in a Rails application. The `after_action` callback is used to ensure that the `set_headers` method is called after every action in every controller. The `X-Frame-Options` HTTP header is a security measure that prevents the browser from displaying the contents of a web page in a `<frame>`, `<iframe>`, `<embed>`, or `<object>` HTML element, unless the web page belongs to the same origin as the web page that includes the HTML element. This is intended to provide some protection against 'clickjacking' attacks. However, the `X-Frame-Options` header is considered deprecated because its protection can be bypassed using several iframe layers. Therefore, relying on this header as the only protection mechanism against clickjacking is a security vulnerability. A more robust solution would be to use the `Content-Security-Policy` header with the `frame-ancestors` directive, which provides a more powerful and flexible way to control which web pages can be displayed in frames. In addition, it is also recommended to use other security measures, such as ensuring that all user input is properly validated and sanitized, using anti-CSRF tokens, and implementing proper session management.

Steps

  1. Replace the use of X-Frame-Options header with Content-Security-Policy header.
  2. Set the Content-Security-Policy header to include 'frame-ancestors' directive with the 'self' value.
  3. Ensure that the 'frame-ancestors' directive does not allow any other domains to frame the application.
  4. Consider implementing additional security measures to prevent clickjacking attacks.

Secure Code Example

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

  private

  def set_headers
    response.headers["Content-Security-Policy"] = "frame-ancestors 'self'"
  end
end

The updated code replaces the deprecated `X-Frame-Options` header with the `Content-Security-Policy` header. The `Content-Security-Policy` header is a more modern and flexible solution for controlling content loading and preventing attacks such as clickjacking. The `frame-ancestors 'self'` directive is used to specify that only the same origin can embed the application in a frame. This means that no other domains can frame your application, providing a stronger protection against clickjacking attacks. This change is a part of a broader strategy to enhance the security of your application. It's recommended to implement additional security measures, such as regularly updating and patching your software, using secure coding practices, and educating your users about the risks of clickjacking and other attacks.


References

  • 152 - Insecure or unset HTTP headers - X-Frame Options

  • Last updated

    2023/09/18