Skip to main content

Missing subresource integrity check

Need

Enforcement of subresource integrity checks

Context

  • Usage of Ruby for building dynamic and object-oriented applications
  • Usage of Ruby on Rails for web application development

Description

Non compliant code

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
@external_js = 'https://third-party.com/external.js'
end
end

# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>SampleApp</title>
<%= javascript_include_tag @external_js %>
</head>
<body>
<%= yield %>
</body>
</html>

In the above code, the index method in ApplicationController is setting @external_js to be the URL of a JavaScript file hosted on a third-party server. This URL is then being passed to the javascript_include_tag helper in the application's layout file, which generates a script tag to load the JavaScript file.

The vulnerability here is that there is no subresource integrity check being performed on this external JavaScript file. This means that if the third-party server is compromised, or if the file is modified in transit, the application will still execute the JavaScript file without any warnings. This could lead to malicious code being executed in the context of the application, potentially leading to a variety of attacks such as Cross-Site Scripting (XSS).

Steps

  • Implement subresource integrity (SRI) checks for external resources.
  • Generate the integrity hash for the external resource.
  • Update the view to include the integrity attribute for the external resource.
  • Verify that the integrity check passes for the external resource.

Compliant code

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
@external_js = 'https://third-party.com/external.js'
@external_js_integrity = 'sha384-XXXX' # Replace 'sha384-XXXX' with the actual hash
end
end

# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>SampleApp</title>
<%= javascript_include_tag @external_js, integrity: @external_js_integrity, crossorigin: 'anonymous' %>
</head>
<body>
<%= yield %>
</body>
</html>

The above code fixes the vulnerability by implementing Subresource Integrity (SRI) checks for the external JavaScript file.

In the ApplicationController, along with the URL of the external JavaScript file, we also define its integrity hash. This hash is a base64-encoded cryptographic hash of the resource's content.

In the application layout file, we include the integrity hash when including the JavaScript file. The integrity attribute in the javascript_include_tag helper method is used to specify the hash. The crossorigin attribute is also added with the value 'anonymous' to allow CORS.

When the browser loads the external JavaScript file, it computes the hash of the received data and compares it with the provided hash. If they match, the browser understands that the file was not tampered with during the transmission and executes it. If they don't match, the browser refuses to execute the file, thus preventing any potential malicious code execution.

Remember to replace 'sha384-XXXX' with the actual hash of the external JavaScript file. You can generate the hash using online SRI hash generators or command-line tools like openssl.

References