Closed moshetanzer closed 2 weeks ago
Hi, can you please share your nuxt.config ? I've hosted the playground on cloudfare, it seems to work
We've been debuggin similar issue with Vercel last month, here are our findings (and example config): https://github.com/Morgbn/nuxt-csurf/issues/28#issuecomment-2194360017
Yip. Not sure why maintainer doesn’t seem to see issue. There are issues open also in the nuxt security package. See the origin solution I posted in Nuxt Security it works well and basically is supported by every browser and is suggested by owasp
Yip. Not sure why maintainer doesn’t seem to see issue. There are issues open also in the nuxt security package. See the origin solution I posted in Nuxt Security it works well and basically is supported by every browser and is suggested by owasp
the aim is to understand where the problem comes from. Not to rewrite this module with another solution. But the lack of reproduction doesn't help. I even hosted the playground on Cloudfare, and it works...
Hey @Morgbn the playground is the repro. Just deploy on Vercel. Not exactly sure how cloudflare infra works.
Playground, with CSRF header, not working. check it out.
Refresh the page and then retry, it works but indeed, the cookie with the csrf token is not set at the first request.
In the mean time, if nothing happens in the first 40 seconds, it seems the CSRF token is invalid
https://github.com/user-attachments/assets/449a69e5-2033-4144-9c85-111030dfd318
See these 2 requests, they fails despite having the same CSRF token
This could come from the encryptSecret
that change from one request to another?
I deploy the playground on my Cloudflare account to check and the key change between two requests (no redeploy). The logs above are the result of the following console.log
import * as csrf from "uncsrf";
import { defineEventHandler, getCookie, getHeader, createError } from "h3";
import { useRuntimeConfig, getRouteRules } from "#imports";
import { useSecretKey } from "../helpers";
import { defuReplaceArray } from "../../utils";
const baseConfig = useRuntimeConfig().csurf;
export default defineEventHandler(async (event) => {
const { csurf } = getRouteRules(event);
if (csurf === false || csurf?.enabled === false) {
return;
} // csrf protection disabled for this route
const csrfConfig = defuReplaceArray(csurf ?? {}, baseConfig);
const method = event.node.req.method ?? "";
const methodsToProtect = csrfConfig.methodsToProtect ?? [];
if (!methodsToProtect.includes(method)) {
return;
}
const secret = getCookie(event, csrfConfig.cookieKey!) ?? "";
const token = getHeader(event, baseConfig.headerName!) ?? "";
const secretKey = await useSecretKey(csrfConfig);
console.log(secret, token, secretKey); // <------ Log in the screenshot above.
// verify the incoming csrf token
const isValidToken = await csrf.verify(
secret,
token,
secretKey,
csrfConfig.encryptAlgorithm
);
if (!isValidToken) {
throw createError({
statusCode: 403,
name: "EBADCSRFTOKEN",
statusMessage: "CSRF Token Mismatch",
});
}
});
@Morgbn is there a way to make it stable?
Hello @Barbapapazes, thanks for the detailed question!
I think I've figured out why after about ten seconds the token changes:
useSecretKey
store secretKey
in a global var, that not compatible with serverless functions...
I'll look for a solution to this problem
It may need some rewrite for the config, if the secretKey should be change after the build, I suggest to generate it in the module at build time and store it in the runtimeConfig
@atinux Wouldn't that break cross-deploy form submissions? And is there something wrong with encryptSecret
being statically defined?
Well it's already the case @bojanrajh
Very good question, I don't see any issue for having the same encryptSecret
but @Morgbn may have more insights about this
I've just come across this issue while using nuxt-security with NuxtHub (cloudflare pages)
Is there some sort of work around or a fix on the horizon?
:tada: This issue has been resolved in version 1.6.4 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
Hi,
As explained here at length this module does NOT work on serverless since state is not saved and if server isn't warm/hot, cold restarts happen all the time which requires page reloads (on user side to update token) basically any time you use a form that has CSRF protection.
This is discussed at length in the nuxt security package https://github.com/Baroshem/nuxt-security/issues/477
Unless this issue is sorted or a different method is used, using this will create a really bad ux in your project. Author is aware of this but has not responded to queries.