Psifi-Solutions / csrf-csrf

A utility package to help implement stateless CSRF protection using the Double Submit Cookie Pattern in express.
Other
123 stars 19 forks source link

this is not an issue but i couldn't find it what we have to do for sending in frontend type hidden after we generate the token #39

Closed aveein closed 1 year ago

aveein commented 1 year ago

exports.getLogin = (req,res,next)=>{ const token = req.csrfToken(true);

    res.render('auth/login',{
        docTitle:'Login',
        path:'/login',
        pageTitle:'login',
        token:token
    });

}

psibean commented 1 year ago

Ah you're right, there is no form or SSR example here.

csrf-sync has a processing as a form example - where csrf-csrf works similarly. In your template, you render the token as a hidden field on your form, similar to this:

<form action="/transfer.do" method="post">
  <input
    type="hidden"
    name="CSRFToken"
    value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZMGYwMGEwOA=="
  />
  [...]
</form>

And you make sure you have configured the getTokenFromRequest option when initializing csrf-csrf, where the key is the name of the form field:

  getTokenFromRequest = (req) =>  {
    return req.body['CSRFToken'];
  }

Please note that you should make this function explicit. The implicit nature of the default behavior in csurf for this same functionality is the reason csurf's default configuration is insecure. If you need to support BOTH form submits and the header option:

  getTokenFromRequest = (req) =>  {
    const contentType = req.headers['content-type'];
    if (contentType.includes('form')) {
        return req.body['CSRFToken'];
    } else {
        return req.headers['x-csrf-token'];
    }
  }

If you need to support multipart form data it gets a bit trickier and you'll need to be familiar with your multipart form processor (e.g. multer - or whatever it is you're using).

aveein commented 1 year ago

still getting invalid csrf i have added getTokenFromRequest app.js

const { doubleCsrf } = require("csrf-csrf");
app.use(cookieParser());
const {
    invalidCsrfTokenError, // This is just for convenience if you plan on making your own middleware.
    generateToken, // Use this in your routes to provide a CSRF hash + token cookie and token.
    validateRequest, // Also a convenience if you plan on making your own middleware.
    doubleCsrfProtection, // This is the default CSRF protection middleware.
  } = doubleCsrf({
    getSecret: () => "Secret", // A function that optionally takes the request and returns a secret
    cookieOptions: {

        secure : false,

      },
   // A function that returns the token from the request
   getTokenFromRequest: (req) => {

    const contentType = req.headers['content-type'];
    if (contentType.includes('form')) {
        return req.body['CSRFToken'];
    } else {
        return req.headers['x-csrf-token'];
    }
  },
  });

app.use(doubleCsrfProtection);

my form

  <form class="login-form" action="/login" method="POST">
  <input type="hidden" name="CSRFToken" value="token" >
</form>
psibean commented 1 year ago

my form

  <form class="login-form" action="/login" method="POST">
  <input type="hidden" name="CSRFToken" value="token" >
</form>

I'm assuming this form also contains the username and password field, as well as a submit button? If the form contains all of the fields and a submit button, then when the submit button is clicked, the POST request will be made to the action path, with all of the field values mapped to their names as form data.

For form data, do you have the body parser middleware registered before csrf-csrf?

This isn't really something that is included in the docs (maybe it would be worth a mention), but the csrf-csrf docs assume you either know, or would otherwise reference express documentation for non csrf-csrf things

aveein commented 1 year ago

yes it is included before csrf-csrf you can see my code here https://github.com/aveein/node-js-csrf

aveein commented 1 year ago

full form code

 <form class="login-form" action="/login" method="POST">
          <input type="hidden" name="CSRFToken" value="<%= token %>" >
            <div class="form-control">
                <label for="email">Email</label>
                <input type="text" name="email" id="email">
            </div>
            <div class="form-control">
                <label for="password">Password</label>
                <input type="password" name="password" id="password">
            </div>

            <button class="btn" type="submit">Login</button>
        </form>
psibean commented 1 year ago

Hey @aveein sorry for the delay, I took a quick look at the repo and it looks like it should work. I'd pull it down and check myself, but there's a bit of stuff in the repo that shouldn't have been checked in. You shouldn't commit the node_modules folder to your repo - this should be in your git ignore file, among other things.

The recommendation I can make to you at this point is when you request your login page, check the Network tab of the dev tools and take a look at the GET request for the login page. Is there any warnings on the Set-Cookie header or anything else that may indicate or imply that the cookie isn't working for some reason?

Depending on your specific local setup, you may need to change the sameSite value and/or the name of the cookie to remove the secure prefix just for development env.

aveein commented 1 year ago

Sorry for my unprofessionalism push i was in hurry to show you my bad Yes, it was with the cookie name that was blocking i think many of were having the same problem. Thank you!! I will refactor it and push it again so that others can see :) Updated : https://github.com/aveein/node-js-csrf This package is awesome!!

psibean commented 1 year ago

Glad it's working!

This is mentioned in the README:

Change for development

The security prefix requires the secure flag to be true and requires requests to be received via HTTPS, unless you have your local instance running via HTTPS, you will need to change this value in your development environment.