4

I'm using Asp.Net Core Webapi 2 with no static content as a backend server + nginx on a separate machine to serve Angular 7 application. Here is the question: does it have sence to try to use xrsf antiforgery protection like services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); in case of splitted back and front machines? As far as I understand I have to manage some kind of state between these two servers to provide corresponding cookie from Nginx which backend server will accept.

1 Answers1

0

If I have understood the question correctly, you want to know how to protect your webapp from CSRF attack.

Your APIs are hosted in a backend web server, whereas the Angular static contents are hosted in nginx.

The idea is explained in Angular docs. You need to set the cookie XSRF-TOKEN (default name) in authentication REST response. The cookie should be secure but readable using javascript (non-httpOnly). You can set the value of the cookie to something unique for the user session (ideally a cryptographically generated random number). Here, onwards in every subsequent request, Angular HttpClient would send the cookie value in the request header X-XSRF-TOKEN and the server needs to validate if the cookie value and the request header value are correct. Note that the access token cookie would also accompany the request (as usual in token based authentication). Thus in every valid API call, your web server would receive the access token in cookie header and the XSRF cookie value in custom XSRF header and XSRF cookie header. If the XSRF header is missing or the values do not match, the server rejects the request.

So, the solution is stateless and managed by storing values in cookie which accompany every request (unless you also maintain the XSRF cookie value in the server for more strict validation).

In your setup, the cookie set by the server is not be visible to the Angular static files served by nginx due to same-origin policy. You can however resolve the issue in one of the following ways:

  1. If your web API server and static file server are accessed using different IPs (say 172.168.1.1 and 172.168.2.2) or different domains (say webapi.com or static.com), you need to configure the web api server to set the following headers in response to allow the static file server (172.168.2.2 or static.com) read the cookies: Access-Control-Allow-Origin: https://static.com

  2. If your web API server and static file server are accessed using different sub-domains (webapi.example.com & static.example.com), you can go either with the above approach or set the domain while setting the cookie: Set-Cookie: name=value; domain=example.com

You may also consider reading this thread for CSRF

Saptarshi Basu
  • 8,640
  • 4
  • 39
  • 58
  • 1
    I know how basicaly XSRF protection works, but there is still somethething that bothering me. In this articles which you provide, the first Angular index page have to be sended by WebApi server (not second static server). And that's something doesn't fit me, I'm having 2 separate servers. – Kirill Polunin Dec 17 '18 at 09:26
  • @KirillPolunin The first page fom the static server is usually a landing page and login page. You need to then authenticate which you would do using one of the OAuth 2.0 grant type (authorization code, implicit or resource owner password). Once the authentication is complete, your server would send the access token to the browser and the cookie would also be sent along with the response. If your static server and backend server are on subdomains of same domain, both servers will get the cookie provided you set the domain name in the `Set-cookie`. – Saptarshi Basu Dec 17 '18 at 09:56
  • On top of the above comment, Angular can redirect the user to the login page, if the cookie is absent – Saptarshi Basu Dec 17 '18 at 09:59
  • yes, but when client goes auth via ajax, and even if WebApi server sends cookie(with XSRF-token) then browser cuts it from response, because this request was made via AJAX, hence Angular app will not receive it, so this auth request should not be done via ajax. May be i'm wrong, but all the time I tried to receive this xsrf cookie via ajax it was empty, even the webapi server set it in response. – Kirill Polunin Dec 17 '18 at 11:58
  • @KirillPolunin that's because your static server and web api server are on two different domains/ips/sub-domains and same-origin policy prevents the cookies to flow through AJAX call. If your servers are on subdomains like webapi.abc.com and static.abc.com, you can set the domain `abc.com` while setting the cookie. If the servers are on different IPs/domains, you can set the CORS settings in webapi server to make its cookies accessible to static file server – Saptarshi Basu Dec 17 '18 at 12:14