Skip to content

Include JavaScript file hashes in entrypoints.json for hash & nonce attributes (CSP) #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
weaverryan opened this issue Oct 23, 2018 · 7 comments · Fixed by #522
Closed
Labels

Comments

@weaverryan
Copy link
Member

Hi guys!

This is an idea that I've just been talking to a few people about: in the entrypoints.json, what if we output the file hashes for all of the JavaScript files? For example:

{
  "app": {
    "js": [
      "build/runtime.js",
      "build/vendors~a33029de.js",
      "build/app.js"
    ],
    "css": [
      "build/vendors~ea1103fa.css",
      "build/app.css"
    ]
  },
  "checkout": {
    "js": [
      "build/runtime.js",
      "build/vendors~a33029de.js",
      "build/checkout.js"
    ],
    "css": [
      "build/checkout.css"
    ]
  },
  "_hashes": {
    "build/runtime.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
    "build/vendors~a33029de.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
    "build/app.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
    "build/checkout.js: "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  }
}

I am far from a security expert, but as I understand it, this would give us 2 possible security-related possibilities - especially when used with the new Twig function in WebpackEncore bundle that outputs your script tags automatically (https://github.com/symfony/webpack-encore-bundle):

  1. A integrity= attribute for Subresource integrity (https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)

  2. A nonce= attribute (set to the same hash), which would allow you to use a CSP that requires nonces for all script tags (a very strict policy). The server could also read these hash values for the CSP header.

Questions:

A) Good idea? Bad idea?
B) Is the integrity= something that's valuable for "self" script/link tags?

@stof
Copy link
Member

stof commented Oct 23, 2018

nonce should not use a hash of the file as the value (as the same value would be used multiple times).

@frankdejonge
Copy link

frankdejonge commented Oct 23, 2018

A little extra context for @stof's comment: For the nonce we need to hash of the individual chunk not from the build.

@stof
Copy link
Member

stof commented Oct 23, 2018

no, for the nonce, you need a generated value (a nonce is meant to be used only once)

@frankdejonge
Copy link

I meant for the CSP header.

@stof
Copy link
Member

stof commented Oct 23, 2018

If you use a nonce in the CSP header, it must be a generated value you change each time, not a static value. Otherwise, a XSS could have a valid nonce on it by using your static value (defeating the point of the CSP)

@Lyrkan
Copy link
Collaborator

Lyrkan commented Oct 24, 2018

I like the idea.

As stof said it can't be used for the nonce attribute, but it would definitely be useful for integrity.

What I like a bit less though is the special _hashes key... I think having something like this would be preferable:

{
	"entrypoints": {
		"app": {
			"js": [
				"build/runtime.js",
				"build/vendors~a33029de.js",
				"build/app.js"
			],
			"css": [
				"build/vendors~ea1103fa.css",
				"build/app.css"
			]
		},
		"checkout": {
			"js": [
				"build/runtime.js",
				"build/vendors~a33029de.js",
				"build/checkout.js"
			],
			"css": [
				"build/checkout.css"
			]
		}
	},
	"hashes": {
		"build/runtime.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
		"build/vendors~a33029de.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
		"build/app.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
		"build/checkout.js": "oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
	}
}

weaverryan added a commit that referenced this issue Nov 2, 2018
…ints.json file (Lyrkan)

This PR was merged into the master branch.

Discussion
----------

Put current data under an "entrypoints" key in the entrypoints.json file

Following my comment in #418 this PR adds an `entrypoints` key in the `entrypoints.json` file instead of putting everything at the root. It also simplifies a bit the code of the `processOutput` function to avoid duplicated code.

For now it won't really matter (since it'll be the only key) but it will avoid using "magic" keys later on if we want to add additional data (such as the hashes of the referenced files).

I'll also open a PR in the `webpack-encore-bundle` repository.

Commits
-------

3a46843 Put current data under an "entrypoints" key in the entrypoints.json file
weaverryan added a commit to symfony/webpack-encore-bundle that referenced this issue Nov 2, 2018
…the entrypoints.json file (Lyrkan)

This PR was merged into the master branch.

Discussion
----------

Read data from an "entrypoints" key instead of the root of the entrypoints.json file

This PR changes how the `entrypoints.json` lookup works in order to support symfony/webpack-encore#424.

Currently the entrypoints are directly listed at the root of the `entrypoints.json` file:

```json
{
  "my_entry": {
    "js": [
        "build/file1.js",
        "build/file2.js"
    ],
    "css": [
      "build/styles.css",
      "build/styles2.css"
    ]
  },
  "other_entry": {
    "js": [
        "build/file1.js",
        "build/file3.js"
    ]
  }
}
```

This works fine but will be a bit annoying later on if we want to add additional data such as [files hashes](symfony/webpack-encore#418) that could be used to automatically handle the `integrity` attribute of the generated `<script>` tags.

A solution to that issue would be to move all the current data under an `entrypoints` key and add new keys when needed (for instance `hashes`):

```json
{
  "entrypoints": {
    "my_entry": {
      "js": [
          "build/file1.js",
          "build/file2.js"
      ],
      "css": [
        "build/styles.css",
        "build/styles2.css"
      ]
    },
    "other_entry": {
      "js": [
          "build/file1.js",
          "build/file3.js"
      ]
    }
  }
}
```

Commits
-------

97bcbae Put current data under an "entrypoints" key in the entrypoints.json file
@Phobetor
Copy link

Phobetor commented Dec 4, 2018

Having the integrity hashes would be a great improvement.

@Lyrkan Lyrkan added the HasPR label Feb 13, 2019
weaverryan added a commit that referenced this issue Mar 29, 2019
…(Lyrkan)

This PR was merged into the master branch.

Discussion
----------

Add an enableIntegrityHashes() method to the public API

This PR adds an `Encore.enableIntegrityHashes()` method that allows to compute integrity hashes of all the files referenced in the `entrypoints.json` (closes #418).

For instance:

```js
// Enable it for all builds with the
// default hash algorithm (sha384)
Encore.enableIntegrityHashes();

// Enable it only in production with
// a custom hash algorithm
Encore.enableIntegrityHashes(
    Encore.isProduction(),
    'sha512'
);
```

And here is the resulting `entrypoints.json` file:
```json
{
  "entrypoints": {
    "main": {
      "css": [
        "/main.3d1dcb7e.css"
      ],
      "js": [
        "/main.7c6b7c81.js"
      ]
    }
  },
  "integrity": {
    "/main.3d1dcb7e.css": "sha384-ce7d1nV3CFoSIfinwm53befb9CMHNAAlPEb61deOf3zBvpXK9lct44/U2ieSOKt4",
    "/main.7c6b7c81.js": "sha384-kHFhNTJlbSuDijSTimOHZGTxKzlLYCWc03AmmRSAE3b173SMlGiQG6uasAzl29+0"
  }
}
```

Commits
-------

fa915aa Add an enableIntegrityHashes() method to the public API
Keemosty12 added a commit to Keemosty12/webpack-encore-bundle that referenced this issue Jun 12, 2025
…the entrypoints.json file (Lyrkan)

This PR was merged into the master branch.

Discussion
----------

Read data from an "entrypoints" key instead of the root of the entrypoints.json file

This PR changes how the `entrypoints.json` lookup works in order to support symfony/webpack-encore#424.

Currently the entrypoints are directly listed at the root of the `entrypoints.json` file:

```json
{
  "my_entry": {
    "js": [
        "build/file1.js",
        "build/file2.js"
    ],
    "css": [
      "build/styles.css",
      "build/styles2.css"
    ]
  },
  "other_entry": {
    "js": [
        "build/file1.js",
        "build/file3.js"
    ]
  }
}
```

This works fine but will be a bit annoying later on if we want to add additional data such as [files hashes](symfony/webpack-encore#418) that could be used to automatically handle the `integrity` attribute of the generated `<script>` tags.

A solution to that issue would be to move all the current data under an `entrypoints` key and add new keys when needed (for instance `hashes`):

```json
{
  "entrypoints": {
    "my_entry": {
      "js": [
          "build/file1.js",
          "build/file2.js"
      ],
      "css": [
        "build/styles.css",
        "build/styles2.css"
      ]
    },
    "other_entry": {
      "js": [
          "build/file1.js",
          "build/file3.js"
      ]
    }
  }
}
```

Commits
-------

97bcbae Put current data under an "entrypoints" key in the entrypoints.json file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants