Skip to content
This repository has been archived by the owner on Nov 3, 2019. 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
enhancement New feature or request

Comments

@morloy
Copy link

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
Copy link
Owner

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.

@ChristopherBiscardi ChristopherBiscardi added the enhancement New feature or request label Mar 4, 2019
@morloy
Copy link
Author

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
Copy link

@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
Copy link
Owner

@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
Copy link

@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
Copy link
Owner

@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
Copy link

@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.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants