0

I want to utilize tornado as a backend server using an Angular 6.x Web Application. If I now send a POST request to my server hosted locally the request arrives but tornado replies with a 403 printing the following:

'_xsrf' argument missing from POST 

Since I don't want to turn off xsfr cookies, I now need a solution how to add this specific argument using Angular 6's HttpClient. Angulars official docs only state, that a token is set for all requests made.

There is a now deprecated version that worked by adding the following to the list of providers defined in app.module.ts. However the docs just state to look at the new HttpClient which was not quite helpful.

{
    provide: XSRFStrategy,
    useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
}

Backend-wise cookies are set on login as following:

def post(self):
    incorrect = self.get_secure_cookie("incorrect")
    if incorrect and int(incorrect) > 10:
        return

    getusername = tornado.escape.xheml_escape(self.get_argument("username"))
    getpassword = tornado.escape.xheml_escape(self.get_argument("password"))

    print(getusername)
    print(getpassword)

    if getusername == "admin" and getpassword == "admin":
        self.set_secure_cookie("user", self.get_argument("username"))
        self.set_secure_cookie("incorrect", "0")
        self.redirect(self.reverse_url("main"))
    else:
        incorrect = self.get_secure_cookie("incorrect") or 0
        increased = str(int(incorrect) + 1)
        self.set_secure_cookie("incorrect", increased)
        self.write("Wrong username or password")

I absolutely see that this is not secure at all, but more security will be added during further development. This is just a basic example to get all the stuff working.

Maybe one of you has already coped with this and has a solution or at least a hint where to look.

xyres
  • 20,487
  • 3
  • 56
  • 85
hGen
  • 2,235
  • 6
  • 23
  • 43

1 Answers1

0

Two things:

  1. You are trying to set the CSRF cookie, whereas Tornado is the one which has already set the cookie previously.
  2. When you submit the form, Tornado expects that you send a form field or a post request parameter called _xsrf whose value is the same as the cookie set by Tornado.

How to fix it:

  1. What you have to do is read the value of the cookie set by Tornado. The cookie's name will be _xsrf.

  2. Then, when you send the POST request, include a field called _xsrf with the value of the cookie in your form data.

xyres
  • 20,487
  • 3
  • 56
  • 85
  • I totally see what you're saying, The only problem is, tornado never sets the cookie because the frontend is not directly served via tornado. Even if I serve the frontend through a StaticFileHandler instance no cookie whatsoever appears on angular side. I tried to implement a simple transaction where angular sends a GET , requesting the cookie token. That works quite well, however Chrome and Firefox block angular setting the cookie by itself. – hGen Nov 04 '18 at 12:35