Skip to content
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

output file hash to manifest #35

Closed
enapupe opened this issue Mar 22, 2017 · 12 comments · Fixed by #66
Closed

output file hash to manifest #35

enapupe opened this issue Mar 22, 2017 · 12 comments · Fixed by #66
Milestone

Comments

@enapupe
Copy link

enapupe commented Mar 22, 2017

What do you guys think about adding hash information to manifest file so we can make use of SRI?
https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity?

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched file must match.

@mastilver
Copy link
Contributor

@enapupe Can you give me an output example?

@enapupe
Copy link
Author

enapupe commented Jul 4, 2017

I could but I realize it's probably not webpack-manifest-plugin job.. I can totally accomplish it with just node. I have the assets path on my express server, I just need to calculate and serve it.

Anyway, I think a good output format would require changing the json object to something more complex like:

{
  "production.js": {
    "file": "production.0b86f4ea34734cae00b2.js",
    "hash": "[hash here]"
  }
}

I'll share my server implementation later.

@enapupe
Copy link
Author

enapupe commented Jul 4, 2017

This is what I ended up with: https://github.com/CheesecakeLabs/react-redux-boilerplate/pull/41/files

I'm probably going to improve it a bit but overall that's the idea.

@mastilver
Copy link
Contributor

I will probably add a reduce option that would allow you to do (in combination with https://github.com/waysact/webpack-subresource-integrity) :

reduce: (manifest, {chunkName, fileName, source}) => {
  return {
    ...manifest,
    [chunkName]: {
      file: fileName,
      hash: source.integrity
    }
  }; 
}

@enapupe
Copy link
Author

enapupe commented Aug 10, 2017

Thank you sir!

@mastilver
Copy link
Contributor

@enapupe NP, let me know how you manage to get it to work this: https://github.com/waysact/webpack-subresource-integrity

@mastilver
Copy link
Contributor

Also would be awesome if you could send us a PR, to add an example under: examples/subresource-integrity ;)

@enapupe
Copy link
Author

enapupe commented Aug 10, 2017

This would be a quick version of SRI hash impementation:

const path = require('path')
const fs = require('fs')
const crypto = require('crypto')

const checksum = (str, algorithm = 'sha384', encoding = 'base64') =>
  crypto.createHash(algorithm).update(str, 'utf8').digest(encoding)

const fileSum = (file, algorithm) =>
  checksum(fs.readFileSync(file), algorithm)

const calculateSRI = (file, algorithm = 'sha384') =>
  `${algorithm}-${fileSum(path.join('.', 'dist', file), algorithm)}`

[...]

new ManifestPlugin({
  fileName: 'production.stats.json',
  reduce: (manifest, { path: filePath, name }) => Object.assign({}, manifest, {
    [name]: {
      file: filePath,
      integrity: calculateSRI(filePath),
    },
  }),
}), 

And an example manifest json file for the above reduce:

{
  "production.css": {
    "file": "production.0a223be5ea0a5e9b73df.css",
    "integrity": "sha384-ghrMahQRvdaAOeuXUx8vTGYaJ4hOamp1x+TMFY6PM6PkNCnHEDEmgZCmcbiGQKTg"
  },
  "production.css.map": {
    "file": "production.0a223be5ea0a5e9b73df.css.map",
    "integrity": "sha384-T1VD7crFyHHqourMswVItpFz/U/b6r039gA9BWSCUD7VlV/8qWvj//ddxyQYwoC/"
  },
  "production.js": {
    "file": "production.0a223be5ea0a5e9b73df.js",
    "integrity": "sha384-HBAJ+je7l8y29QXxU+cJVK3+l4enaVpMNilziQYuyehDBq/SMvfYYR7NtAQV7ikv"
  },
  "production.js.map": {
    "file": "production.0a223be5ea0a5e9b73df.js.map",
    "integrity": "sha384-V4iQc+wLch9RpT8r/N2W16s4x/0Xv3Dpl894m0bAWWoCnfDUFf2VUMwkjTlDWihk"
  }
}

@mastilver
Copy link
Contributor

Cool 👍 , I guess this wouldn't work with webpack-dev-server though

@enapupe
Copy link
Author

enapupe commented Aug 10, 2017

Yeah, it reads from FS so no. But I'm not sure why it should... It seems unnecessary.
Do you have any other ideas on how to get this? I looked into the second argument but I couldn't find any Stream or similar in-memory source.

@RinkAttendant6
Copy link

@enapupe I tried the above code but it seems to run before the files are written to the file system?

Here's the error:

Error: ENOENT: no such file or directory, open '/media/GitHub/app1/public/blog/assets/js/contact-form.min.js'
    at Object.fs.openSync (fs.js:646:18)
    at Object.fs.readFileSync (fs.js:551:33)
    at fileSum (/media/GitHub/app1/webpack.config.js:26:77)
    at calculateSRI (/media/GitHub/app1/webpack.config.js:27:70)
    at files.reduce (/media/GitHub/app1/webpack.config.js:234:40)
    at Array.reduce (<anonymous>)
    at Object.generate (/media/GitHub/app1/webpack.config.js:228:46)
    at ManifestPlugin.<anonymous> (/media/GitHub/app1/node_modules/webpack-manifest-plugin/lib/plugin.js:153:28)

@UXDart
Copy link

UXDart commented Jun 5, 2018

I have the same problem as @RinkAttendant6 , the files are not there yet... using webpack 4... and using 'generate'... any idea? TIA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants