Frontend Security: npm-audit and Script integrity
Tags: html, javascript, security
Published: 2021-01-14 05:51:08

A couple of years ago, thousands of websites globally were hijacked by code, which made computers run cryptocurrency mining software.

[Discovered by renowned security-expert Scott Helme](https://scotthelme.co.uk/protect-site-from-cryptojacking-csp-sri/), the malicious code was injected into a 3rd party accessibility-script, “browsealoud” by a company called texthelp.

Among the hijacked sites were most UK government sites, the website of the swedish police, and many more.

There's no doubt about where the crimes of the future will take place, so it's surprising to see, how few websites take security seriously.

And I admit, it's a hard sell: Unlike new, cool UI-components, engaging animations, creative user-journeys etc., security isn't sexy — it's not even visible!

But it will be the day, a security flaw scrapes important data, or otherwise ruins revenue.

Security should be an ongoing strategy for any company, but **who** should maintain it? Some of it is clearly front-end related.

---

## npm-audit

The first line of defense is fixing frontend-assets. If your site use `node_modules`, test for vulnerabilities by running [npm-audit](https://docs.npmjs.com/cli/v6/commands/npm-audit):
`$ npm run audit`, optionally with the `--fix` parameter.
The latter will try to fix vulnerabilities, as well as give you a report with further steps to take. Yes, some projects contains 500MB+ of `node_modules`, but it has to be done.

---

## 3rd party scripts and `integrity`
I have a project where I'm using **unpkg** to deliver a script.   
**unpkg** is a fast, global content delivery network for everything on npm.

```js
<script defer
  src="https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js">
</script>
```

Now, if **unpkg** gets hacked, my site will get the hacked script.

Luckily, there's an attribute called `integrity`, which we can add to `<script>`-tags. It's a SHA-key, generated from the (unhacked) script-source. If the script is hacked, the key will not match anymore, and the script will *not* load. The hack I mentioned at the beginning of this post could have been prevented, if the affected sites had used the `integrity`-attribute.

For **unpkg**-scripts, append `?meta` to the end of the url:

```html
https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js?meta
```

 This will return a json-string/object:

```json
{
  "path":"/dist/smoothscroll.min.js",
  "type":"file","
  contentType":"application/javascript",
  "integrity":"sha384-EYn4rWu1DHvYD0sSSSbMEtXQmMl58CFJd897806+RT1jJVYbhuZlZMN6yG9nCyFa",
  "lastModified":"Tue, 26 Mar 2019 18:21:19 GMT",
  "size":3968
}
```

Take the *integrity*-part and add to your `<script>`-tag — and add a `crossorigin`-attribute as well:

```js
<script defer
  src="https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js"
  integrity="sha384-EYn4rWu1DHvYD0sSSSbMEtXQmMl58CFJd897806+RT1jJVYbhuZlZMN6yG9nCyFa"
  crossorigin="anonymous">
</script>
```

The official name is “Subresource Integrity”, and most of the large CDN's and script-delivery-services support it.  

Documentation is here:
https://w3c.github.io/webappsec-subresource-integrity/

In an upcoming article, I'll focus on how to set up and configure a *Content Security Policy*.

Thanks for reading!