Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do i have to use csrf protection in React SPA?

I use React Single Page Application as a client side or Create React App (CRA).

In my backend i use Node.js & Express.

to fetch data or store i need to call API from client to backend.

actually I've seen there are several middleware like: - Express CSURF

but to be honest I don't understand how to send a CSRF token to the client every request. I have tried several times, by inserting the CSRF into a cookie and then taking it on the client side. but when the first request or new cookie is stored, I get error Invalid CSRF Token.

and even though I did this:

app.use(session({
    genid: function (req) {
        return uuidv4() // use UUIDs for session IDs
    },
    name:keys.session.name,
    secret: keys.session.secret,
    resave: false,
    saveUninitialized: true,
    rolling:true,
    cookie: { 
        secure: false,
        httpOnly: true,
        maxAge:keys.session.maxAge, // satu hari,
        sameSite:true,
     }

}));
app.use(passport.session());
app.use(cookieParser());
app.use(csrf({ cookie: false }));


app.use((req,res,next)=>{
     res.cookie('CSRF_token', req.csrfToken(), { sameSite: true });
})

Which means the CSRF_token cookie will change each request. but I only set it once like this : axios.defaults.headers.common['csrf-token'] = csrf; and the results its still work, which should not working.

So do I need CSRF? or how to configure the correct one on react SPA.

like image 257
Faris Dewantoro Avatar asked Feb 07 '19 10:02

Faris Dewantoro


People also ask

How Spa stop CSRF?

To protect against CSRF attacks we need to ensure there is something in the request that the evil site is unable to provide. One solution is to use the Synchronizer Token Pattern. This solution is to ensure that each request requires, in addition to our session cookie, a randomly generated token as an HTTP parameter.

Does react protect against CSRF?

Luckily, it's easy to implement CSRF protection in React. You only have to store the CSRF token in your React app and generate relevant headers to send along with the request to the server. The server will quarantine all CSRF requests.

Do REST API need CSRF protection?

Enabling cross-site request forgery (CSRF) protection is recommended when using REST APIs with cookies for authentication. If your REST API uses the WCToken or WCTrustedToken tokens for authentication, then additional CSRF protection is not required.

Do you need CSRF with JWT?

There's no way someone can abuse XSS and take your JWT to impersonate you. If you put your JWTs in a header, you don't need to worry about CSRF. You do need to worry about XSS, however. If someone can abuse XSS to steal your JWT, this person is able to impersonate you.


1 Answers

So do I need CSRF?

As stated here: Am I under risk of CSRF attacks in a POST form that doesn't require the user to be logged in? I think you should still set it.

As for why it is not working for you, I assume it is because of the header name. You may check what CSURF checks by default.

The default value is a function that reads the token from the following locations, in order:

  • req.body._csrf - typically generated by the body-parser module.
  • req.query._csrf - a built-in from Express.js to read from the URL query string.
  • req.headers['csrf-token'] - the CSRF-Token HTTP request header.
  • req.headers['xsrf-token'] - the XSRF-Token HTTP request header.
  • req.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header.
  • req.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header.

Going by what CSURF checks, you have a variety of options to choose from, and looking at axios, it seems to have a couple options for setting xsrf cookie and header names.

...
// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
xsrfCookieName: 'XSRF-TOKEN', // default

// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
...

For example, in order to use the X-XSRF-TOKEN header key axios comes with by default, I used the following method in my App.js file:

componentDidMount() {
    axios.get(`/api/csrf`) // Send get request to get CSRF token once site is visited.
      .then(res => {
        axios.defaults.headers.post['X-XSRF-TOKEN'] = res.data; // Set it in header for the rest of the axios requests.
      })
  }

You could, however, use a form hidden input or any other method you're comfortable with. You can read more about why it's common to put them in cookies here.

I'm not sure what you're using for your client, but if you're using Redux, you may look here for help. If it doesn't work, you may Google other methods.

like image 86
yaserso Avatar answered Oct 21 '22 03:10

yaserso