Openrefine: Add CSRF protection to all POST endpoints

Created on 22 Sep 2019  路  3Comments  路  Source: OpenRefine/OpenRefine

We should add Cross Site Request Forgery protection to all our POST endpoints, to protect instances from being altered by other sites (which can be the first step in a XSS exploit).

  • [x] add GET method to generate CSRF tokens
  • [x] require and validate CSRF tokens in all POST endpoints. We probably want to do that in a generic way in the Command class.
  • [x] update the frontend to request such tokens before POSTing
vulnerability

Most helpful comment

The typical exploit is as follows:

Assume someone is running OpenRefine at http://localhost:3333/ on their machine.
Simultaneously, they go to http://maliciouswebsite.com/. That website includes a script which submits a form to a POST endpoint in OpenRefine, say http://localhost:3333/command/core/set-preference. This POST request can be triggered without any user interaction (just create a hidden <form> element and submit it in javascript). Submitting forms across different domains is allowed, so the request will not be blocked by the browser's policy. This will let the attacker modify any OpenRefine preference silently, for this command (and of course you can come up with scarier scenarios with other commands).

Now with a CSRF protection, the attacker first needs to obtain a token from OpenRefine. To do so, they need to perform a cross-domain GET request to our backend and see the result of that request to read the token. That is not allowed by the cross-origin policy.

All 3 comments

@wetneb I came across this while looking at the current AJAX code and am wondering how much protection it provides. A typical attack, as I understand it, would consist of using the user's cookie based session authentication to make an unauthorized change, but OpenRefine users aren't authenticated in the first place. Additionally, since the CSRF token is fetched separately from the generated web page from unauthenticated end point, an attacker could just request a token and then use it in their forged request.

There's probably something that I'm missing here, so figured I'd ask.

The typical exploit is as follows:

Assume someone is running OpenRefine at http://localhost:3333/ on their machine.
Simultaneously, they go to http://maliciouswebsite.com/. That website includes a script which submits a form to a POST endpoint in OpenRefine, say http://localhost:3333/command/core/set-preference. This POST request can be triggered without any user interaction (just create a hidden <form> element and submit it in javascript). Submitting forms across different domains is allowed, so the request will not be blocked by the browser's policy. This will let the attacker modify any OpenRefine preference silently, for this command (and of course you can come up with scarier scenarios with other commands).

Now with a CSRF protection, the attacker first needs to obtain a token from OpenRefine. To do so, they need to perform a cross-domain GET request to our backend and see the result of that request to read the token. That is not allowed by the cross-origin policy.

Got it. Thanks! It was the CORS piece that I was missing.

Was this page helpful?
0 / 5 - 0 ratings