I have a web application which uses an external authentication server for obtaining a session. When a client tries to login, the browser is making requests towards the external authentication server until a cookie is obtained. Note that the client has all the API calls towards the external authentication server.
My concern is that an attacker can clone my web application and trick the user into going to his web application, for example with typosquatting. The malicious web application can then interact with the legitimate external authentication server. Doing this will give the malicious web application a legitimate cookie, which the attacker can use on the legitimate web application. I consider this to be a form of CSRF.
There are two approaches I can think of to tackle this:
- Have CORS enabled on the external authentication server. Allow the
Originto be equal to only one value, i.e. the web application URL. Now, when the malicious web application tries to interact with the legitimate external authentication server, the client's browser will include a
Originheader which the external authentication server will reject (due to CORS).
- Use tokens as a classic CSRF protection. Essentially, connect the legitimate web application server talk to external authentication server, and have them establish a transient token for each client (e.g. based on the IP). The client would get this token as part of the login form and send it to the external authentication server with the requests. The external server can then decide if the token is valid for that specific client.
- Client makes a request to web application -> Web application establishes a token with the external authentication server -> Web application gives the client the token -> The client sends the token to the external authentication server with the requests.
I would like to evade the second option if possible, taking into account that I have some additional risk of assuming that the clients always use a CORS compatible browser. Do you think the first option is enough? If not, are your concerns solved by the second option? Is there another option that I am overlooking?