Cross-Origin Resource Sharing(CORS)
General idea
By default, for security reasons, browsers don’t accept requests from an origin (domain) to another one for some kinds of requests (for example XMLHttpRequest or GET with custom header). But by enabling CORS (in the server side), the server may tell to the browser to accept kind of requests from other domains that usually blocks.
In a word : it allows to make strictless the same origin policy of browser for specify origin/methods/headers.
From Mozilla documentation :
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
Same origin policy is not a security mitigating for web applications
It is not a way at all to solve security holes/issues and more particularly CSRF.
It covers only a very tiny part of cross domain/site surface attack.
And only browsers are designed to honor that.
Which means that you can bypass with it curl or any client that allows to perform http re
Concretely
Two features :
– for any (idempotent or not) requests, the server that receives a request adds in the headers response some information for the browser that indicates whether the domain that has performed the request is authorized to read the response.
The server returns header such as :
Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET Access-Control-Allow-Origin: http://localhost:4200 |
– for requests considered as not « simple », essentially, it means no idempotent requests (that changes the state of the application such as POST/PUT/DELETE) and requests with particular headers or content type.
See the whole list here, the browser sends a preflighted request to the server to ask whether the request is safe to be executed.
The preflighted request is performed via the OPTION method. It contains the access control headers that the request uses, for example that for a request that adds a header authorization :
Access-Control-Request-Headers: authorization Access-Control-Request-Method: GET |
If the server authorizes that kind of requests for that domains, it returns something like :
Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: authorization Access-Control-Allow-Methods: GET Access-Control-Allow-Origin: http://localhost:4200 |
The browser can so send the original request with the GET method and the authorization header such as :
Authorization: Basic YTphTutuTutu
Cross-Site Request Forgery (CSRF)
General idea
From the owasp site :
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request.
Concretely
That attack is possible for any request that changes the state : GET (incorrectly chosen by the server) POST, PUT, DELETE requests.
For example, suppose a bank website where GET methods allow no-idempotent requests (it is an major security issue of course). The attacker will rely on the URL that allowed logged users of a website to transfer a XXX amount to a XXX account:
GET http://bank.com/transfer.do?targetAccount=XXX&amount=XXX
The attacker simply change the data to allow the transfer to his account :
GET http://bank.com/transfer.do?targetAccount=dudu&amount=9999
Then with social engineering, the attacker makes the victim to execute that request (mail with html content that loads that request via IMG or A tags or encourage the victim to click on a link with that).
If at that time the victim is logged on bank.com, the request is processed by the server and the attack is done.
For POST methods, the attacker cannot use an A or an IMG tag. A FORM tag is required.
Either the victim is encouraged to click on the link that sends the form with the data chosen by the attacker (the forged request) or the attacker sends the form as soon as the loading of the page (body onload
attribute in JavaScript).
How to mitigate CSRF ?
See here.
The recommended ways are token.
A common way is the Synchronizer token pattern. Here token are generated by the server side once by session and transmitted then by client in the request header.
That solution is stateful (the token is stored in the server side) and requires multiple requirements (challenge token for each sensitive requests, checks of the validity of the received token, …).
There is other token strategies that don’t require the server to be stateful but these have some other constraints.
There is also other techniques. For example, the double submit cookie is a lighter alternative (easy to implement and stateless) but it doesn’t reduce so much the attack surface than token-based strategies.