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

add option to log hashes of svelte style blocks (needs svelte patch too) #21

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rouilj
Copy link
Contributor

@rouilj rouilj commented Feb 3, 2023

When command-pal runs, svelte inject style blocks into the page. These style blocks will not be applied if you use Content Security Policies (CSP) to secure your web application. To allow them to be applied, you need to add hashes for the style blocks to the style-src (or default-src) CSP settings.

This patch adds a reportStyleHash option to CommandPal. This along with a modification to the append() function in the node module svelte/internal/index.mjs results in console.log
output like:

svelte-1qhguwm-style 'sha256-gwaXl9ypsP5M+Pl7IPC4TdkehJgQRvkKmcYSf6NCydU='
svelte-bvn01s-style 'sha256-uBf9jI60SnIb3YTm/PeNRoEUOwpLyiOgSOmdm9XR8v8='
svelte-1ary9cc-style 'sha256-RpNJcpPx5tmGIdPUg0nsHLh99/fW3Gh85m5Kr+izRG8='
svelte-zz386-style 'sha256-flay8qiGrAOgKV+HMGAUkHtP0Ff+D+FyO2PBYlnYM78='

where the second element is the hash and the first element is the id for the injected style block. The hashes (including the ') can be copied into a CSP string.

You should calculate these for your copy of the command-pal JavaScript library. They should remain the same as long as the library isn't updated.

To make this work also requires a change be made to a node-module used to build command-pal.

The file node-modules/svelte/internal/index.mjs needs a modified definition of the append() function. Modify the append function by inserting:

if ( node.tagName === "STYLE") {
  cp_hashFromString(node.id, node.innerText).then(
    function (value) {if (value) { console.log(value) }}
  )
}

at the beginning of the function.

This patch includes two versions of cp_hashFromString. It will use it's internal definitions only if cp_hashFromString is undefined. If window.cp_hashFromString collides with a different function or something that is not a function, you will get an error and CommandPal will not work.

If reportStyleHash is set to false (default), the version that is used just returns null. This suppresses console output. If reportStyleHash is set to truthy it invokes a version from
https://stackoverflow.com/a/69486709 to return the base64 encoded sha256 hash for the style. When the browser calculates the sha256 hash for the injected style it sees that it matches a sha256 in the CSP header and applies the style block.

You can also define a cp_hashFromString in script tag in your web page before invoking CommandPal. In this case, your version will be used so you could generate sha512 hashes if you wanted.

Note this is a hack. There should be some way to externalize the injected style blocks so they can be included using <style nonce="...">. This would eliminate the need to update the CSP with each new CommandPal release. But I am only smart enough to work around it this way.

See #13 for more details.

When command-pal runs, svelte inject style blocks into the page.
These style blocks will not be applied if you use Content Security
Policies (CSP) to secure your web application. To allow them to be
applied, you need to add hashes for the style blocks to the style-src
(or default-src) CSP settings.

This patch adds a reportStyleHash option to CommandPal. This along
with a modification to the append() function in the node module
svelte/internal/index.mjs results in console.log
output like:

  svelte-1qhguwm-style 'sha256-gwaXl9ypsP5M+Pl7IPC4TdkehJgQRvkKmcYSf6NCydU='
  svelte-bvn01s-style 'sha256-uBf9jI60SnIb3YTm/PeNRoEUOwpLyiOgSOmdm9XR8v8='
  svelte-1ary9cc-style 'sha256-RpNJcpPx5tmGIdPUg0nsHLh99/fW3Gh85m5Kr+izRG8='
  svelte-zz386-style 'sha256-flay8qiGrAOgKV+HMGAUkHtP0Ff+D+FyO2PBYlnYM78='

where the second element is the hash and the first element is the id
for the injected style block. The hashes (including the ') can be
copied into a CSP string.

You should calculate these for your copy of the command-pal JavaScript
library. They should remain the same as long as the library isn't
updated.

To make this work also requires a change be made to a node-module
used to build command-pal.

The file node-modules/svelte/internal/index.mjs needs a modified
definition of the append() function. Modify the append function by
inserting:

    if ( node.tagName === "STYLE") {
      cp_hashFromString(node.id, node.innerText).then(
        function (value) {if (value) { console.log(value) }}
      )
    }

at the beginning of the function.

This patch includes two versions of cp_hashFromString. It will use
it's internal definitions only if cp_hashFromString is undefined. If
window.cp_hashFromString collides with a different function or
something that is not a function, you will get an error and CommandPal
will not work.

If reportStyleHash is set to false (default), the version that is used
just returns null.  This suppresses console output. If reportStyleHash
is set to truthy it invokes a version from
https://stackoverflow.com/a/69486709 to return the base64 encoded
sha256 hash for the style. When the browser calculates the sha256 hash
for the injected style it sees that it matches a sha256 in the CSP
header and applies the style block.

You can also define a cp_hashFromString in script tag in your web page
before invoking CommandPal. In this case, your version will be used so
you could generate sha512 hashes if you wanted.

Note this is a hack. There should be some way to externalize the
injected style blocks so they can be included using <style
nonce="...">. This would eliminate the need to update the CSP with
each new CommandPal release. But I am only smart enough to work
around it this way.
@rouilj
Copy link
Contributor Author

rouilj commented Feb 3, 2023

The change to App.svelte may not be required. As I was building a bundle from merging my branches
I noticed build warned that the variable def in App.svelte was unused. I included it because I was
monkey see/monkey do for the change for placeholder. I removed the change to App.svelte and the code/bundle
still works.

When not using localhost or https, the crypto libraries are unavailable.
Detect this case and alert the user.
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 this pull request may close these issues.

1 participant