-
Notifications
You must be signed in to change notification settings - Fork 10
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
Question on /csrf-token endpoint #49
Comments
Typically the recommended way to share a csrf-token with the client is by it placing it in a const resp = await fetch('/page-with-csrf-token-in-meta-tag');
const html = await resp.text();
// use regex to parse `<meta name="csrf-token" content="xxx">` here... One possible attack that they're trying to protect against is that if the CSRF protection is a deep field so I don't want to say with 100% certainty that you can disregard that comment but I can't see how the specific Incidentally, if you want to move the CSRF token to the // app/layout.tsx
import { Metadata } from 'next';
import { headers } from 'next/headers';
export async function generateMetadata(): Promise<Metadata> {
const csrfToken = headers().get('X-CSRF-Token') || 'missing';
return {
title: 'edge-csrf examples',
other: {
'csrf-token': csrfToken,
},
};
}
export default function Layout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
} And the const handleSubmit = async (ev: React.FormEvent<HTMLFormElement>) => {
// prevent default form submission
ev.preventDefault();
// get form values
const data = new FormData(ev.currentTarget);
// get token from <meta> tag
const metaTag = document.querySelector('meta[name="csrf-token"]');
const csrfToken = metaTag ? metaTag.getAttribute('content') : 'missing';
// build fetch args
const fetchArgs = { method: 'POST', headers: {}, body: JSON.stringify(data) };
if (csrfToken) fetchArgs.headers = { 'X-CSRF-Token': csrfToken };
// send to backend
const response = await fetch('/form-handler', fetchArgs);
// show response
// eslint-disable-next-line no-alert
alert(response.statusText);
}; |
Thanks for your detail explanation. I was looking at their recommendation to get the token "Signed Double-Submit Cookie". With CORS disabled in your example, I don't see how an attacker can gain access to the csrf token either. Method-1:
Method-2:
Is this understanding flawed? |
This library implements the "signed double-submit cookie pattern" with a modification that instead of using a shared server-side secret, it uses a unique per-session secret (stored in a cookie). The advantage of this is that it doesn't require the developer to define an environment secret. The token is signed with the secret and both the secret (via cookie) and the token (via payload) must be present in the request and pass validation as described in the "signed double-submit cookie" pattern. Here are the relevant lines in the source code for reference: With regards to "Method-1", if CORS is disabled then a With regards to "Method-2", it sounds like you're describing a pattern that retrieves the token from the initial HTTP response. If so, then that will also be safe but you should keep in mind that typically cookies in the "double-submit cookie pattern" have Going back to your original question, the main advantage of using a |
thanks @amorey for your prompt response. |
Hi,
I am quite new to CSRF and was using your library for NextJS 14.
Can I check with regards to this portion of code fetch("/csrf-token"):
and middleware.ts
is this endpoint /csrf-token suppose to be there in production as well? or this is just an example?
I am reading article which indicate CSRF token should not be accessed with AJAX which confuses me with your example.
Thanks
The text was updated successfully, but these errors were encountered: