Skip to main content
Image
Drupal Seguridad

Subresource Integrity (SRI) in Drupal 7

Context

The particular problem occurs when the client asks us to improve the security in one of the portals that run on Drupal 7. The client attaches a security report where, through certain tools such as Security Headers or the Security Observatory Mozilla identifies vulnerabilities through an analysis of the headers and elements of the web page.

The goal from this point is to correct these vulnerabilities and obtain a better score. So far so good, right?

One of the most critical points and the one with the most points left in the Mozilla Observatory review is precisely the SRI or Subresource Integrity header. This feature allows the browser to identify if an external resource has not been manipulated or violated, since it has two attributes that identify exactly what they are like; something like that with β€œDNA from an external resource”.

  • Integrity : This is the first attribute, and contains a base64-encoded string or hash that certifies that the external resource has not been tampered with since it was created.
  • Crossorigin - is the second attribute, and manages how the browser will treat this resource. It is usually described as β€œanonymous” for external resources with a domain other than the origin and that does not require credentials during the request to it.

We already have the context and the problem on the table. Now, how do we implement Subresource Integrity on all the external resources of our Drupal 7 site?

Solution with AdvAgg Subresource Integrity

From Drupal 8 onwards there are many facilities regarding the implementation of SRI. In Drupal 7 things are different, and depending on the external resources we have on the web, things can get complicated.

The first step is to install the AdvAgg module and the AdvAgg Subresource Integrity submodule. This module will automate the addition of SRI to almost all the external resources of the portal, being able to configure the integrity level of the resource (the hash that is generated).

Once you clear caches, many of your external resources will have SRI immediately, simply wonderful.

At this point we only have to check from the Mozilla Observatory if all our resources have SRI enabled and celebrate with a beer.

Oh wait… that beer will have to wait.

Manual solution

Sometimes not everything is so simple and pretty (ahem, Drupal 7 nudge, nudge) and requires us to roll up our sleeves and think. At this point, we are left with only one way to fix this: locate and add SRI to the required external resources manually. Let us begin! I promise you it won't be that bad...

Resource location

The Mozilla Observatory tells us β€œwhat fails but not who causes it.” To locate external resources that do not have SRI enabled we have two options:

  • Option A: Search the browser's element inspector and locate them one by one.
  • Option B: use the tool that I am going to tell you and finish before lunchtime.

The tool that helped me a lot is SRI-CHECK . This simple and powerful tool requires python pip and is responsible for analyzing a URL in search of resources that do not have SRI implemented. Once installed, it shows us the following:

I have 5 external resources that are loading without SRI. Additionally, two of them are being loaded with HTTP, which deducts many more points from the Mozilla Observatory for being more insecure.

SRI Implementation

To implement SRI on the resources that we have located, we will follow the following steps:

  1. Create a custom module for said functionality; for example, β€œmymodule_sri” or β€œsri”.
  2. We will create the file β€œsri.module”.
  3. We implement the hook_js_alter to override the attributes of all these resources. I leave you a code fragment with an example:
/**
 * Implements HOOK_js_alter().
 */
function sri_js_alter(&$javascript) {
  // Implements SRI.
  $javascript['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js']['attributes']['crossorigin'] = 'anonymous';
  $javascript['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js']['attributes']['integrity'] =
    'sha384-aBL3Lzi6c9LNDGvpHkZrrm3ZVsIwohDD7CDozL0pk8FwCrfmV7H9w8j3L7ikEv6h';
}

To enter the β€œ Integrity ” parameter you can easily obtain a hash for your resource here: https://www.srihash.org/ . Enter the sha (signature) of your resource provided by this website in the β€œintegrity” attribute and… that's it! To solve the HTTP problem, you can use this same hook and add the following to override the src:

$javascript['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js']['data'] =
  'https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';

The second external resource marked in red in the previous image I could not change from here, since it is not a javascript. To solve this I looked in the core where this url came from and found that it is a W3C specification of GRDDL (a type of markup). I used a template_preprocess_html to override the variable that contained said url, as follows:

/**
 * Implements template_preprocess_html().
 */
function mymodule_preprocess_html(&$variables) {
  // Change http provided by the core to https.
  $variables['grddl_profile'] = 'https://www.w3.org/1999/xhtml/vocab/';
}

Remember that this goes in the template.php file of your custom theme !

Conclusion

The conclusion of this post is that not everything is what it seems and that it is necessary to pay more attention to the security of our website. A hug and see you soon!

Tags

Join the Drupal Sapiens Community

Save content that interests you, connect with others in the community, contribute to win prizes and much more.

Login or create an account here

Latest posts

Featured

Last news