Skip to content
This repository has been archived by the owner. It is now read-only.

Support a strict CSP without 'unsafe-eval' #303

Closed
morloy opened this issue Mar 1, 2019 · 7 comments
Closed

Support a strict CSP without 'unsafe-eval' #303

morloy opened this issue Mar 1, 2019 · 7 comments
Labels

Comments

@morloy
Copy link

@morloy morloy commented Mar 1, 2019

Is your feature request related to a problem? Please describe.
We had been using a strict Content-Security-Policy on our website. After switching from Remark to MDX we noticed that it doesn’t work anymore. The reason for this is this call, that evaluates JS code in string:

const fn = new Function("_fn", ...keys, `${children}`);

Describe the solution you'd like
Allowing unsafe-eval open the possibility to some XSS attacks. Thus, it would be nice to have MDX working without it.

I’m not an expert on this, but maybe Gatsby allows to programatically create pages from the React code that results from MDX.

@ChristopherBiscardi

This comment has been minimized.

Copy link
Owner

@ChristopherBiscardi ChristopherBiscardi commented Mar 4, 2019

You can use createPage with a component that points directly to the .mdx file, or use the src/pages support. Note that both of these options means you'll have to use MDX layouts for page layout instead of the usual Gatsby layout approach.


The core of why the function constructor is used is that MDX compiles to React code that needs to be executed while markdown compiles to HTML. Typically remark is inserted with the dangerouslysetinnerhtml api, so they both expose you to roughly the same surface area for XSS. There are two ways to use MDX, one is similar to the dangerouslysetinnerhtml approach in remark (using MDXRenderer) and the other is using the mdx-loader by setting the createPage component to an .mdx file or using the src/pages support.

I'm open to different approaches that might allow more regular Gatsby usage for layouts, etc and also remove the function constructor usage. One idea I have is similar to what rehype-react does, in which we could have a HASTRenderer which takes the HAST AST and converts it to createElement calls. It would be a bit of work and we'd have to clone some of the mdx-ast-to-jsx code (and ship said code in the HASTRenderer runtime) but I think it would solve the problem you're having nicely and also allow the dynamic nature of MDX (using MDXProvider, etc) to still work.

@morloy

This comment has been minimized.

Copy link
Author

@morloy morloy commented Mar 4, 2019

Thanks for your comments, @ChristopherBiscardi. One difference between unsafe-eval and dangerouslySetInnerHTML is that the former affects your whole website, whereas the latter only affects MDX pages.

@aTechGuide

This comment has been minimized.

Copy link

@aTechGuide aTechGuide commented Aug 23, 2019

@morloy @ChristopherBiscardi I'm facing the same issue. Could you please share a working example of how to go about it, please.

Basically, I create dynamic pages via the following code

function createPosts(posts, createPage, templates) {
  posts.forEach(({ node }) => {
    createPage({
      path: node.frontmatter.slug,
      component: require.resolve('./src/templates/single-post.js'),
      context: {
        slug: node.frontmatter.slug
      }
    });
  });
}

I use require.resolve('./src/templates/single-post.js') as I'm using gatsby theme.

So I'm not exactly sure how to go about,

You can use createPage with a component that points directly to the .mdx file,

@ChristopherBiscardi

This comment has been minimized.

Copy link
Owner

@ChristopherBiscardi ChristopherBiscardi commented Aug 23, 2019

@aTechGuide use the src/pages support that does this by default or your createPages call needs to point to a mdx file: require.resolve('./src/templates/single-post.mdx')

@aTechGuide

This comment has been minimized.

Copy link

@aTechGuide aTechGuide commented Aug 24, 2019

@ChristopherBiscardi Thank you so much for such a prompt response. I did try the fix in my gatsby theme but it seems the unsafe-eval error is still coming

PR for the fix: https://github.com/aTechGuide/gatsby-theme-blog-starter/pull/1/files

Please let me know If I'm missing something and thanks for your help.

Screenshot 2019-08-24 at 12 06 27 PM

@ChristopherBiscardi

This comment has been minimized.

Copy link
Owner

@ChristopherBiscardi ChristopherBiscardi commented Aug 25, 2019

@aTechGuide You're still seeing the issue because you haven't fundamentally changed your code. You can't use MDXRenderer at all: https://github.com/aTechGuide/gatsby-theme-blog-starter/blob/a04562c5d59e2ebe4642bf57200c07d90fa52aa1/src/components/post/FullPost.js#L141

If you want to use createPage you have to use posts/thirdPost/003-third-post.md as the path to the component. Otherwise use the built-in src/pages support.

@aTechGuide

This comment has been minimized.

Copy link

@aTechGuide aTechGuide commented Aug 28, 2019

@ChristopherBiscardi ah, I see now.
I've updated the code and the unsafe-eval error is gone.

These are my changes: aTechGuide/gatsby-theme-blog-starter#1

Thank you so much @ChristopherBiscardi for all your help. Really appreciate it

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.