How to Use SRI Tags in JavaScript to Prevent Malicious Scripts?

Content verified by Anycode AI
July 21, 2024
Modern web applications make use of many third-party scripts and CDNs, all of which enhance functionality, hence performance. However, this also increases the security risk, since those external sources can be compromised and result in malicious code injected into your website. Subresource Integrity is a very doable and strong security feature addressing this vulnerability, allowing browsers to check integrity before execution. It will cover how to implement SRI tags in JavaScript, which creates a very robust protection against script modification. By the end of these steps, only verified and unchanged scripts will be executed, and a web application can be very well protected from any kinds of potential attacks that may arise from compromised third-party sources or CDNs.

Subresource Integrity (SRI) is a neat security feature that helps browsers make sure the files they fetch, like scripts from a CDN, haven't been tampered with. Essentially, it lets you set up a cryptographic hash that the fetched file must match. If the retrieved file’s integrity doesn't match the hash you provided, the browser will not load it, discarding it as if it failed to fetch in the first place. This is a solid way to guard against resource hijacking.

Alright, let's dive into how you can use SRI tags in JavaScript to keep those pesky malicious scripts at bay, step by step:

How to Use SRI Tags

Get the Resource Hash:

First things first, you need the cryptographic hash of the resource you want to load. This hash is what will be used to verify the file’s integrity.

You can get this hash using command-line tools like shasum or even online resources.

For instance, with shasum:

curl https://cdn.example.com/script.js | shasum -a 384

Running this command will give you an output like:

abc123def456...  -

Choose the Right Hash Algorithm:

The commonly used hash algorithms are:

  • SHA-256
  • SHA-384
  • SHA-512

It’s generally better to go with a stronger one like SHA-384 or SHA-512.

Incorporate the SRI Hash in HTML:

Now that you've got the hash, you can plug it into your HTML using the integrity attribute. Don’t forget the crossorigin attribute if the file is being loaded from a different origin.

<script src="https://cdn.example.com/script.js"
        integrity="sha384-Abc123Def456..."
        crossorigin="anonymous"></script>

Practical Example

Imagine you’re loading jQuery from a CDN.

Generate the SRI Hash:

First, you’ll want to download and hash the jQuery file. For example:

curl https://code.jquery.com/jquery-3.6.0.min.js | shasum -a 384

This command might give:

sha384-9/aliU8dGd2tb6OSsuzixeV4y/faTqgf  Ftohetphbbj0= .    -

Apply the Hash in HTML:

Next, place the hash in the integrity attribute within your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Secure Script Loading</title>
</head>
<body>
    <!-- Load jQuery library with SRI and crossorigin attributes -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha384-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
            crossorigin="anonymous"></script>
    <script>
        // Your custom JavaScript code here
        $(document).ready(function(){
            console.log("jQuery and custom scripts loaded securely!");
        });
    </script>
</body>
</html>

Important Considerations

Updating Resources:

If you update the hosted resource, don’t forget to update the integrity value too. Otherwise, the browser will reject the new resource.

Cross-Origin Resource Sharing (CORS):

Use the crossorigin attribute with SRI. Without it, the integrity check might fail. Usually, set it to anonymous unless your requests need credentials.

Error Handling:

If a resource fails the integrity check, it's treated as a failed load. Make sure your app can handle these scenarios smoothly.

Performance:

SRI can slightly impact loading times due to the extra hash verification, but the security benefits more than make up for this minor cost.

Host Integrity Verification:

Trust the CDN or host where you're fetching resources from. SRI guards against tampering during transit, but not against malicious scripts right at the source.

Advanced Usage

Using SRI in a Build Process:

You can automate the SRI hash generation and insertion in HTML during your build process using tools like webpack or gulp.

Webpack Example:

Install webpack and webpack-subresource-integrity-plugin:

npm install --save-dev webpack webpack-cli webpack-subresource-integrity

Configure webpack.config.js:

const SubresourceIntegrityPlugin = require('webpack-subresource-integrity');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: __dirname + '/dist',
        crossOriginLoading: 'anonymous'
    },
    plugins: [
        new SubresourceIntegrityPlugin({
            hashFuncNames: ['sha384'],
            enabled: true
        }),
    ],
};

Include the Output in Your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Webpack SRI</title>
</head>
<body>
    <script src="dist/bundle.js"></script>
</body>
</html>

Incorporating SRI checks into your development and deployment process is like putting a lock on the doors and windows of your app, ensuring that everything’s safe and sound from nasty tampering threats. It takes some mindful planning and, of course, keeping things updated, but it's a worthy investment for your web app's overall security.

Have any questions?
Our CEO and CTO are happy to
answer them personally.
Get Beta Access
Anubis Watal
CTO at Anycode
Alex Hudym
CEO at Anycode