-
Notifications
You must be signed in to change notification settings - Fork 22
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
next-safe
as Next.JS 12 Middleware
#12
Comments
@nibtime has provided a very thorough example implementation for this. |
Hi, as I elaborated #36, I found out, that using import _nextSafe from 'next-safe';
import type { Chainable } from 'next-safe-middleware';
import { chain, provideHashesOrNonce } from 'next-safe-middleware';
// because of type bug.
const nextSafe = _nextSafe as unknown as typeof _nextSafe.nextSafe;
const isDev = process.env.NODE_ENV === 'development';
const addSecurityHeaders: Chainable = async (req, res) => {
const headers = nextSafe({
isDev,
contentSecurityPolicy: {
'script-src': [`'strict-dynamic'`, `'unsafe-inline'`, 'https: http:'],
'style-src': [`'unsafe-inline'`],
'connect-src': [
`'self'`,
'https://www.datocms-assets.com',
'https://o1107586.ingest.sentry.io',
'https://sentry.io',
'https://vitals.vercel-insights.com',
'https://site-api.datocms.com',
...(req.cookies.__next_preview_data__
? ['https://graphql-listen.datocms.com']
: []),
],
'img-src': [
`'self'`,
'data:',
'https://www.datocms-assets.com',
'https://i.ytimg.com',
'https://flagcdn.com',
],
},
});
headers.forEach((header) => res.headers.set(header.key, header.value));
};
export const middleware = chain(addSecurityHeaders, provideHashesOrNonce)(); Instead of placing the config in the headers function of It has additional benefits because you can depend the config on request data. For instance, I want Edit: Wrong, you can (see here) but it's really cumbersome I think. In middleware, this is way easier and cleaner with conditional spreading. This alone I think is simple enough and maybe just a "add to docs" issue? Then you can do additional stuff further down the chain, like |
Hi @nibtime, would love to be able to help with this. I tried creating the nonce and passing it through to the env via the config but it does not actually update it everytime the page is hit... On your example above, where are the |
Hi @kiily, the If you want to use it in production I'd strongly recommend something like Sentry (https://docs.sentry.io/product/security-policy-reporting/) and e2e health checks. I made small ad-hoc demo pages to test and explain stuff to myself: https://site-zcm-git-nibtime-issue24-zcm.vercel.app/csp-test/dynamic ( https://site-zcm-git-nibtime-issue24-zcm.vercel.app/csp-test/static ( https://site-zcm-git-nibtime-issue24-zcm.vercel.app/csp-test/isr/any-slug-you-like ( A bit of background to the problem you encountered and how those Whether you can use a nonce or not depends on the prerendering strategy of a page. Nonces only work for pages with For pages with To get hashes of routes with The |
Hi @nibtime , Thanks for getting back to me and thanks for the very in-depth clarification. I tried an implementation with middleware myself, passing the I eventually solved the problem for the case of I can put a small repo together to showcase that approach but also keen to be part of the discussion with @trezy. Been looking at making some open-source contributions myself and this seems like an ideal task. Middleware would be a very nice way to fix this. Let me know how I can help with testing or if I you want me to take a look at that code. |
Hi @kiily you're welcome, I am glad if it was helpful. I just packaged my solution up and published to NPM: @next-safe/middleware. I updated my project also to consume the version NPM, so the links above use this package now, before they used a local transpiled version. If you would test the package in a showcase repo that would be great! I will publish ffrom my private monorepo PR for now. Eventually, the code should become part of an open-source project and properly maintained. The approach this package solves the case for The package also includes the source code if you want to have a look at it and compare approaches. I suspect once go into making it work with Using CSP in Meta Tag also has another disadvantage: Report-Only mode doesn't work and can't be integrated with |
Hi @nibtime, that's awesome. I have been quite busy with work but have started testing in a separate repo. I'll update here with what I find once I am done (at some point before the end of this week). I'll have a look at the implementation you have and compare it with the Speak soon and thanks again for all the help 🙏 |
Hi @kiily, I've been in DevOps mode lately for projects of mine, so I attempted a setup for the lib as well: I set it up as a monorepo with yarn 3, swc bundling, releasing with changesets and e2e testing on Vercel. I can at least draft proper releases now, was very annoying from private project PR 😄. So src is now publicly available and in sync with what's being published to NPM. I also played around with StackBlitz and made a demo where you can test production builds really quickly: https://stackblitz.com/edit/nextjs-km7zwa Cached prod rebuilds take around 5-10s to serve. WebContainer seem to be really fast. If you want to test things out and don't have much time I can really recommend that. I also would advise against going into the |
Damn @nibtime, you've been absolutely smashing it, that's amazing! I'll give it a go on the StackBlitz, things were working well on my example repo. Going to tidy it up and publish it here as well. Thank you so much for your time and help 🙏 |
Thanks @kiily 😄. I am glad that was helpful for you. I've just released I've never done/published any public project before, but so far it's been a really fun way for me to learn and experiment with great new tech. If you like to participate at some time you're more than welcome. |
@nibtime terribly sorry for such a long silence... A lot of work got in the way and I am now looking at this again 🙏 I'm stuck on a Any tools you can recommend for testing that the CSP is all correct before going live would be great. I'll make sure to report back this time if I finally get it all working 🙏 |
still gathering info...
The text was updated successfully, but these errors were encountered: