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

Issues with gatsby-image #3

Open
thomkrupa opened this issue Mar 5, 2019 · 13 comments
Open

Issues with gatsby-image #3

thomkrupa opened this issue Mar 5, 2019 · 13 comments
Assignees
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@thomkrupa
Copy link
Member

I'm having issues with gatsby-image that generates inline styles.

gatsbyjs/gatsby#10890 (comment)

@thomkrupa thomkrupa added the bug Something isn't working label Mar 5, 2019
@thomkrupa thomkrupa self-assigned this Mar 5, 2019
@thomkrupa
Copy link
Member Author

Unfortunately, it's not a bug and can't be fixed unless the gatsby-image changes its behavior.

Gatsby-image uses inline styles in style attributes (as opposed to inline <style> elements). According to the CSP specification, hashes should apply to inline <style> elements only, not to style attributes.

@thomkrupa thomkrupa added help wanted Extra attention is needed question Further information is requested and removed bug Something isn't working labels May 22, 2019
@k8martian
Copy link

k8martian commented Aug 7, 2019

I have my image mess up to 20x20 size. I am unsure if this is the cause of that. Any suggestion how to use this with gatsby image?

@thomkrupa
Copy link
Member Author

hey @k8martian, you can add a custom style-src directive with unsafe-inline value, something like:

{
      resolve: `gatsby-plugin-csp`,
      options: {
        directives: {
          "style-src": "'self' 'unsafe-inline'",
        }
      }
}

That should resolve your issue with gatsby-image.

@NWRichmond
Copy link

@thomkrupa I'm having issues with that, because a nonce is set in style-src, so 'unsafe-inline' is ignored.

From the browser console:
"Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'unsafe-inline' <URL> 'sha256-...[TRIMMED] 'sha256-...[TRIMMED]'". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

@NWRichmond
Copy link

It looks like mergeStyleHashes should be set to false if you want to include unsafe-inline in style-src without having it be ignored due to the presence of a hash value.

{
      resolve: `gatsby-plugin-csp`,
      options: {
        mergeStyleHashes: false, // you can disable styles sha256 hashes
        directives: {
          "style-src": "'self' 'unsafe-inline'",
        }
      }
}
@thomkrupa
Copy link
Member Author

@NWRichmond exactly. I will update readme to make it more clear.

@titenis
Copy link

titenis commented Sep 14, 2020

readme still not updated

@skoldborg
Copy link

CSP rules are there for a reason, setting "style-src" to "unsafe-inline" is convenient for the developer but bad for the user as it's a possible vector for XSS attacks.

See these references for more info:
https://developers.google.com/web/fundamentals/security/csp#inline-code-considered-harmful
https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-4---css-escape-and-strictly-validate-before-inserting-untrusted-data-into-html-style-property-values

@NWRichmond
Copy link

@skoldborg while I agree that the best practice is to have a totally buttoned-up CSP, at the time of this Issue's creation, unsafe-inline was required in order to use gatsby-image:

Unfortunately, it's not a bug and can't be fixed unless the gatsby-image changes its behavior.

Gatsby-image uses inline styles in style attributes (as opposed to inline <style> elements). According to the CS

If you have suggestions for accommodating inline styles in style attributes without unsafe-inline, please share them.

@yesh
Copy link

yesh commented Sep 16, 2021

Hi, same here, I'm trying to add CSP to my gatsby project and solved almost all the issues, but the problem comes with gatsby-plugin-image.

afaik this CSP plugin does not look for, and apply hashes to, scripts and styles outside of head, prebody, etc, as noted here.

the possible solution is to make the plugin generate sha256 hashes also for styles and scripts inside the body.

anyone able to create a pr with a fix?
I'd do it myself if I knew how.

cheers!

@vinassefranche
Copy link

Hi all!
I managed to fix the issue on my project where I created a custom plugin based on this one.

The specificities of the project are:

  • I only care about the scripts as I need to set 'unsafe-inline' for the style-src directive for other reasons.
  • I don't set the CSP with the meta tag in each page. I temporary store all the hashes in a file during the build and at the end, I use them to set the CSP header on my provider.

I'm using onRenderBody to get the scripts that are in the body and compute their hashes:

export const onRenderBody = ({pathname, bodyHtml}, { enabled, hashesCacheFilePath },) => {
  if (!enabled) {
    return;
  }
  console.log(`Building body hashes for file '${pathname}'`);

  const regex = /<script.*?>(.*?)<\/script>/g
  const hashes = [...bodyHtml.matchAll(regex)]
    .map(match => match[1])
    .filter(htmlString => htmlString)
    .map(computeHashOnHtmlString);

  if(hashes.length === 0){
    return;
  }
  const currentHashes = JSON.parse(fs.readFileSync(hashesCacheFilePath));
  fs.writeFileSync(
    hashesCacheFilePath,
    JSON.stringify(uniq([...currentHashes, ...hashes])),
    "utf8",
  );
}

I still have the onPreRenderHTML method which computes the hashes for the scripts in the head, preBody and postBody and it's not an issue as I have my cache file.

I don't know how to translate this to using the meta tag, though. Maybe we can read its current value and replace it with the new value but I might not be easy. If anybody knows a solution, I'll gladly create the P.R. for it.

It would easy to make this work for the styles.

Hope this helps!

@hoijnet
Copy link

hoijnet commented Feb 26, 2023

From what I understand based on the mozilla.org docs on CSP Style Sources, if styles are applied directly on the elements using Javascript, nonces are very effective. Another alternative is like @thomkrupa mentions, to use <style> sections and put nonces in them.

Quoting the section from over there:

However, styles properties that are set directly on the element's style property will not be blocked, allowing users to safely manipulate styles via JavaScript:

document.querySelector("div").style.display = "none";

I use strict-dynamic on my website for making it easier to manage CSP correctly and it is a pain to use gatsby-image as it does not scale, I need to add a lot of sha256 hashes to make it work and it's a lot of friction to my use of Gatsby even if I am very happy about other aspects.

If it were possible to configure gatsby-image to use <style> elements instead somehow, and allow a nonce to be set on them it would be fantastic. The nonce would probably be added automatically through gatsby-plugin-csp-nonce though so even easier. This would mean to move away from inline styles and it sounds like a lot of work though which is a pity.

The alternative to support the inline styles through unsafe-inline is like @skoldborg mentions, unsafe and should be avoided to keep users out of harms way.

strict-dynamic is a solid option for getting CSP right, and would be great if possible to make work for core Gatsby parts all the way!

@hoijnet
Copy link

hoijnet commented Feb 26, 2023

@skoldborg while I agree that the best practice is to have a totally buttoned-up CSP, at the time of this Issue's creation, unsafe-inline was required in order to use gatsby-image:

Unfortunately, it's not a bug and can't be fixed unless the gatsby-image changes its behavior.
Gatsby-image uses inline styles in style attributes (as opposed to inline <style> elements). According to the CS

If you have suggestions for accommodating inline styles in style attributes without unsafe-inline, please share them.

@NWRichmond, if setting the inline styles through Javascript is an option, if could be possible to get a good solution working for it perhaps?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
8 participants