Skip to content
This repository has been archived by the owner on Oct 24, 2021. It is now read-only.

CSP Helmet example needs to cover hashes for modern and legacy bundles #719

Open
jankapunkt opened this issue May 17, 2021 · 0 comments
Open
Labels
good first issue Good first issue or something that should is nice to do.

Comments

@jankapunkt
Copy link
Contributor

The current helmet example assumes a modern bundle (see line 37) but this would fail for legacy bundles. A potential fix could be like the following:

...

  // Prepare runtime config for generating the sha256 hash
  // It is important, that the hash meets exactly the hash of the
  // script in the client bundle.
  // Otherwise the app would not be able to start, since the runtimeConfigScript
  // is rejected __meteor_runtime_config__ is not available, causing
  // a cascade of follow-up errors.
const hashes = [true, false].map(isModern => {
  const runtimeConfig = Object.assign(__meteor_runtime_config__, Autoupdate, {
    accountsConfigCalled: true, // this may depend on, whether you called Accounts.config
    isModern: isModern
  })

  // add client versions to __meteor_runtime_config__
  Object.keys(WebApp.clientPrograms).forEach(arch => {
    __meteor_runtime_config__.versions[arch] = {
      version: Autoupdate.autoupdateVersion || WebApp.clientPrograms[arch].version(),
      versionRefreshable: Autoupdate.autoupdateVersion || WebApp.clientPrograms[arch].versionRefreshable(),
      versionNonRefreshable: Autoupdate.autoupdateVersion || WebApp.clientPrograms[arch].versionNonRefreshable(),
      // comment the following line if you use Meteor < 2.0
      versionReplaceable: Autoupdate.autoupdateVersion || WebApp.clientPrograms[arch].versionReplaceable()
    }
  })

  const runtimeConfigScript = `__meteor_runtime_config__ = JSON.parse(decodeURIComponent("${encodeURIComponent(JSON.stringify(runtimeConfig))}"))`
  return crypto.createHash('sha256').update(runtimeConfigScript).digest('base64')
})

...

const helpmentOptions = {
  contentSecurityPolicy: {
    blockAllMixedContent: true,
    directives: {
      defaultSrc: [self],
      scriptSrc: [
        self,
        // Remove / comment out unsafeEval if you do not use dynamic imports
        // to tighten security. However, if you use dynamic imports this line
        // must be kept in order to make them work.
        unsafeEval,
        `'sha256-${hashes[0]}'`
        `'sha256-${hashes[1]}'`
      ],
...
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Good first issue or something that should is nice to do.
Projects
None yet
Development

No branches or pull requests

2 participants