Michalis
Michalis

Reputation: 6926

CSRF - Is it safe to ask it with api call?

I'm using session based CSRF on a site using Angular. Is it safe to make an HTTP call to ask for the CSRF token?

For example, if I sent a request with valid user session to a page called /csrf/get and it prints a raw token, is this secure enough for CSRF functionality? If not, is there anything I can do to make it more secure while keeping the JSON retrieval functionality?

It will be the first api call before everything else and I will keep it on localstorage to use it on every http call

Upvotes: 13

Views: 4006

Answers (2)

lucascaro
lucascaro

Reputation: 19267

In short, no. The way that you are trying to do CSRF protection exposes you to CSRF since your csrf/get endpoint is not protected from CSRF.

Essentially, you need to protect yourself from two main attack vectors: XSS, and CSRF.

CSRF

CSRF involves your site and a malicious site that will attempt to make authenticated requests to your site. If there is a way to request a CSRF token from the malicious site, you are not protected. Usual methods for protecting from CSRF are by returning a token from your authentication API call, and storing that token in the browser session. The problem with this method is that it opens you up to XSS.

XSS

Cross-Site scripting, or XSS vulnerabilities are related to external scripts running on your page. This includes potentially malicious scripts inserted by an attacker.

Local storage and session storage are not safe, so you shouldn't store a token in regular cookies, for example.

To be safe from XSS attacks Your authentication response can store cookies that javascript can't read by using HttpOnly cookies.

So, using a token that you store with javascript protects you from CSRF, but opens you up to XSS, where using a session cookie protects you from XSS, but opens you up to CSRF.

Protect your API from XSS and CSRF

The solution is to use both approaches: your authentication API should set an HttpOnly cookie to protect from XSS, and should return a token to protect from CSRF.

Note that there's no need for a csrf/get api since the token should be returned by the authentication method: you want to only send that token in exchange of valid credentials. Remember to also send and validate that same token on all authenticated API calls.

Here is a great article explaining API security, why and how to do it in much more detail: http://www.redotheweb.com/2015/11/09/api-security.html

Note on login CSRF:

Logic forms should also be protected from CSRF by creating pre-sessions with CSRF tokens.

(from https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#login-csrf)

Most developers tend to ignore CSRF vulnerability on login forms as they assume that CSRF would not be applicable on login forms because user is not authenticated at that stage, however this assumption is not always true. CSRF vulnerabilities can still occur on login forms where the user is not authenticated, but the impact and risk is different.

For example, if an attacker uses CSRF to assume an authenticated identity of a target victim on a shopping website using the attacker's account, and the victim then enters their credit card information, an attacker may be able to purchase items using the victim's stored card details. For more information about login CSRF and other risks, see section 3 of this paper.

Login CSRF can be mitigated by creating pre-sessions (sessions before a user is authenticated) and including tokens in login form. You can use any of the techniques mentioned above to generate tokens. Remember that pre-sessions cannot be transitioned to real sessions once the user is authenticated - the session should be destroyed and a new one should be made to avoid session fixation attacks. This technique is described in Robust Defenses for Cross-Site Request Forgery section 4.1.

Upvotes: 8

Eugene Mihaylin
Eugene Mihaylin

Reputation: 1776

First of all, use https, http is unsafe.

Then, better not to use GET.

Safe way is to send token in successfull auth request's (POST) response.

For more info, check:

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Upvotes: 1

Related Questions