3

I Have a project with the backend on a MEAN stack started with AngularJS Full-Stack generator and an app under Ionic, when i try to do a POST request to do a login from the Ionic app the server says "CSRF token missing"

{"error":{"message":"CSRF token missing","stack":"Error: CSRF token missing\n    at checkCsrf (/Volumes/Data/Dev/carry/back/node_modules/lusca/lib/csrf.js:89:18)\n    at /Volumes/Data/Dev/carry/back/node_modules/lusca/index.js:48:21\n    at hsts (/Volumes/Data/Dev/carry/back/node_modules/lusca/lib/hsts.js:25:9)\n    at /Volumes/Data/Dev/carry/back/node_modules/lusca/index.js:48:21\n    at xframe (/Volumes/Data/Dev/carry/back/node_modules/lusca/lib/xframes.js:12:9)\n    at /Volumes/Data/Dev/carry/back/node_modules/lusca/index.js:48:21\n    at xssProtection (/Volumes/Data/Dev/carry/back/node_modules/lusca/lib/xssprotection.js:16:9)\n    at /Volumes/Data/Dev/carry/back/node_modules/lusca/index.js:48:21\n    at lusca (/Volumes/Data/Dev/carry/back/node_modules/lusca/index.js:53:9)\n    at Layer.handle [as handle_request] (/Volumes/Data/Dev/carry/back/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/Volumes/Data/Dev/carry/back/node_modules/express/lib/router/index.js:312:13)\n    at /Volumes/Data/Dev/carry/back/node_modules/express/lib/router/index.js:280:7\n    at Function.process_params (/Volumes/Data/Dev/carry/back/node_modules/express/lib/router/index.js:330:12)\n    at next (/Volumes/Data/Dev/carry/back/node_modules/express/lib/router/index.js:271:10)\n    at /Volumes/Data/Dev/carry/back/node_modules/express-session/index.js:432:7\n    at /Volumes/Data/Dev/carry/back/node_modules/connect-mongo/lib/connect-mongo.js:305:11\n    at handleCallback (/Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb/lib/utils.js:96:12)\n    at /Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb/lib/collection.js:1341:5\n    at handleCallback (/Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb/lib/utils.js:96:12)\n    at /Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb/lib/cursor.js:670:5\n    at handleCallback (/Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb-core/lib/cursor.js:154:5)\n    at nextFunction (/Volumes/Data/Dev/carry/back/node_modules/mongoose/node_modules/mongodb-core/lib/cursor.js:675:5)"}}

eventhough it as seen in the request sends the token and other data

POST /auth/local HTTP/1.1
Host: 192.168.1.13:9000
Connection: keep-alive
Content-Length: 47
Accept: application/json, text/plain, */*
X-DevTools-Emulate-Network-Conditions-Client-Id: 552547EB-CA80-4AF8-8392-DDE2A9D833A4
Origin: file://
User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; E5803 Build/32.0.A.4.11; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/48.0.2564.106 Mobile Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-US
Cookie: connect.sid=s%3AKpTipuTW9UAqmbx_X__fuDrfGxXiGRpF.%2FKf2gm3y%2F0VwBzUygchh7%2BVfi6PLoQZhOfI5T22XlxY; XSRF-TOKEN=iZvZ2wKb3VafJb9ZGqily3pBY3nGI9gVBQaww%3D
X-Requested-With: com.todomicilio.app

i don't modify the default configuration of the express server

Andres Vargas
  • 328
  • 1
  • 3
  • 14

3 Answers3

4

Seems you forgot to add csrf token in <form></form> that you use for making POST in html.

In your data there is CSRF token only in cookies, you also need to have CSRF token in form (or in special http request header, it depends on protection implementation).

A couple words about Cross-Site Request Forgery (CSRF):

  1. How to make CSRF attack:

Imagine that we have a website "hacker.example" and also we know about another website "bank.example" that operates with money. Imagine, that bank.example has a POST method /send-money to send money from current user account to another account with receiver-account parameter and bank use cookie for user authorization.

Imagine, that user from bank entered to hacker's website and click on button that submit form to bank.example/send-money with hacker's value for receiver-account parameter. So, browser will make this POST request to bank.example website with cookies for bank.example(!), so, if bank doesn't have protection for CSRF, this request will be authorized and hacker will get a money from that user.

  1. How to protect CSRF attack (one of the possible solutions):

You can put two secret tokens: one in cookie and one for each post request for website. Server should compare this two tokens every time user make post request.

  1. Why does it work?

Now, hacker.example should know csrf token to make appropriate POST request. Hacker have only two possible options to get it: from cookies for bank.example or extract csrf token from html code from bank.example.

But hacker.example don't have access to cookies from bank.example because of security policy and hacker.example cannot get html page to extract csrf token from <form> from bank.example because of CORS.

Timur Bilalov
  • 2,832
  • 1
  • 14
  • 14
1

If you don't want to use CSRF tokens, disable Lusca.

Please refer bellow link

https://github.com/angular-fullstack/generator-angular-fullstack/issues/1582

krish007
  • 46
  • 8
0

Though It's little late, yet I would like to answer, since I faced same problem. Here is the solution to problem:

https://github.com/angular-fullstack/generator-angular-fullstack/pull/2613

"When express.static() is serving index.html it breaks the middleware chain and avoids the CRSF to be set on / request, causing the first login to fail, whenever users have no cookies set.

I think this relates and possibly fixes #2224, #2511, #2611 and krakenjs/lusca#95

This commit basically renames _index.html to app.template.html which is more expressive, and the generated file will be app.html which avoids express.static() blocking the middleware chain, because there is no index.html anymore. Therefore routes.js:sendFile is effectively called.

Note that I tried and played around A LOT with webpack trying to find another solution, this was the most elegant one I could find."