From wikipedia about Same Origin Policy
https://en.wikipedia.org/wiki/Same-origin_policy
The same-origin policy helps protect sites that use authenticated sessions. The following example illustrates a potential security risk that could arise without the same-origin policy. Assume that a user is visiting a banking website and doesn't log out. Then, the user goes to another site that has some malicious JavaScript code running in the background that requests data from the banking site. Because the user is still logged in on the banking site, the malicious code could do anything the user could do on the banking site. For example, it could get a list of the user's last transactions, create a new transaction, etc. This is because the browser can send and receive session cookies to the banking site based on the domain of the banking site.
This part i understood but now...
The user visiting the malicious site would expect that the site he or she is visiting has no access to the banking session cookie. While it is true that the JavaScript has no direct access to the banking session cookie ...
Because the session cookie is httpOnly flagged?
... it could still send and receive requests to the banking site with the banking site's session cookie. Because the script can essentially do the same as the user would do, even CSRF protections by the banking site would not be effective.
Same Origin Policy prohibits Cross-Origin reads. Thus, if we assume that SOP is not enforced, the malicious site could read the CSRF token from the response? Is that the reason why wikipedia is saying that even CSRF protections would not be effective?
Yes, you've understood it. Without the SOP, the malicious script would simply request whatever page has the CSRF token, read it, and then use that token to construct its unsafe requests.
So SOP and CSRF protection are both necessary to protect the user in a world where the browser sends authentication cookies with requests from foreign domains.
Related
Recently I'm studying some basics of Web security and there is something I couldn't understand.
How do anti-CSRF tokens work in SPA-API communications?
As far as I understand, anti-CSRF is used in SPA-API communications as followings;
The browser sends a login request to the API.
The API servers generates a token and sends it back to the browser.
The browser stores it, and when the browser makes the next request, token with be sent together.
The API can make sure that the request came from the genuine front-end because it contains the token.
A question pops up in my mind--how can it prevent CSRF?
If the token is stored in cookie, it will automatically be sent to API whenever a request happens, like usual session cookies. And even if it's stored in other storage(like session storage or local storage), it can be accessed using JavaScript.
So once users are attracted to the attacker's site, anti-CSRF tokens are completely useless.
On the top of that, I can't understand what's the difference between anti-CSRF token and usual cookies used in authentication/authorization……
Maybe I've made a terrible misunderstanding about how anti-CSRF tokes work. Please put a finger on what's wrong about it.
One of the most common CSRF vulnerabilities exists when an attacker can submit a request to an endpoint using an authenticated user's cookies. If you're not using cookies (i.e., to authenticate a user's request) or some other automatic authentication technique (like HTTP Basic Authentication), then there's generally no need for CSRF tokens.
Example #1:
Let's say you're using a REST API that depends on an access token or bearer token for authentication. This token is usually submitted in the HTTP Authorization header (not a cookie). In this case, as long as authentication isn't automatic (e.g., using a cookie), then there's no need for a CSRF token.
Example #2:
In this case, let's say the browser does send a session cookie to a web service/API to authenticate the request. Then, yes, you would be vulnerable to CSRF if anti-CSRF controls aren't implemented. One way to prevent this is to provide an anti-CSRF token to the browser when the SPA is loaded. The browser can then send that token with the request to the endpoint. The web service will then have to validate that token when the request is received.
There are a number of ways that this validation can occur. This could be done using double-submit cookies, a cookie-to-header token, cryptographic techniques, or even a shared database.
Using Anti-CSRF Tokens:
Anti-CSRF tokens generally should not be stored in cookies. As stated in the OWASP CSRF Prevention Cheat Sheet:
A CSRF token can be included in the <meta> tag. All subsequent calls
in the page can extract the CSRF token from this <meta> tag. It can
also be stored in a JavaScript variable or anywhere on the DOM.
However, it is not recommended to store it in cookies or browser local
storage.
For example, an anti-CSRF token might get embedded in the page as:
<meta name="csrf-token" content="{{ csrf_token() }}">
Where the csrf_token() calls some server-side function that embeds the token in the tag.
It can then be read in JavaScript using:
let csrf_token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
And then transmitted to the server when an API request is made (e.g., in a X-CSRF-Token header in a POST request). In addition, the token should be unique to the session.
However, even if a token were to be stored in a cookie, the cookie could be set with the HttpOnly header. This prevents the cookie from being read by JavaScript. This is more so useful in mitigating cross-site scripting (XSS) attacks.
Additional Info:
This StackExchange Security question includes a lot of good info on using CSRF protection in REST APIs.
Other good resources about CSRF in general:
https://portswigger.net/web-security/csrf
https://owasp.org/www-community/attacks/csrf
Like a lot of people lattely, I have a few problems with SameSite and secure.
We have a website, where our user must be logged in to buy some stuff.
When our user want to pay, he is then redirected to the payment plateform. Once he has made the payment he is then redirected to our website.
The problem is that with browsers such as chrome he is no longer logged in,; and we can't display the order informations anymore. Many of our user did not understand and attemps to order multiple time.
From what I understood (How can I redirect after OAUTH2 with SameSite=Strict and still get my cookies?), because of the samesite policy is by default Lax, when he is being redirected to the payment interface and then back to our website, the cookies chain is broken and the cookies from our website are not send, and that is why our user is no longer connected.
I could set Samesite to none but then that would means that our website is vulnerable.
I also made a few research with content secure policy and was wondering if using CSP it was possible to set Samesite=none and with CSP to be able to prevent ?
If you don't specify the samesite flag, only Chrome/Edge will treat them as Lax be default. Setting your cookies to SameSite=none will not make them more insecure that they were before "lax by default" in Chromium or in other browsers.
Lax by default protects your users from tracking and CSRF. If you have some other CSRF mitigation in place you are probably not vulnerable when setting SameSite=none. CSP doesn't help you in this case.
Lets say an attacker controlling site B is exploiting the session a user has with site A.
I know that the attacker is able to exploit the trust server A has for the user, but I don't understand how. Explanations of CSRF I have read make it seem like when the attacker makes a request to site A that the browser automatically includes the necessary authentication information because there is an active session and thus the attack is successful.
The 'browser automatically includes the authentication information' is what doesn't make sense to me. In applications I've worked on auth tokens or cookies are sent explicitly by the client code. So if the client code is specifying what header the token is being sent in for instance, how could the attacker know this?
I'm building SPA app with server side rendering, using JWT-based authentication.
Current implementation is:
JWT token is issued and transferred to client after successful username and password verification
token is then stored in cookie (not HttpOnly) - the purpose of that is to avoid the need to login again after full refresh or closing page
logging out deleted cookie with token
Authorization header is attached to every API request if token exists
full SSL traffic
I can't store token in LocalStorage because of server side rendering, also the there is no HttpOnly because I need to access cookie in order to construct Authorization header.
What are the possibilities of stealing the token in such architecture?
One major risk is that any single cross-site scripting vulnerability in your application could be used to steal the token from the cookie, because it's not httpOnly (while I understand why that is the case). XSS in a javascript-heavy application like an SPA is very common and hard to avoid.
Also you're saying the token is kept in the cookie so that after closing the browser, the user is still logged in. On the one hand, that's bad practice, a user closing the browser probably expects being logged out. On the other hand, this means the cookie is persisted to disk, so it is much easier for an attacker to steal it from the client.
Another thing that comes to mind is cross-site request forgery (CSRF), but if I understand correctly, authentication is actually based on the Authorize header, where the token is copied in each request. If that's the case, CSRF is not an issue for you (but it would be, if sending the token in the cookie was enough).
So at the very least, I think you should
not use a persisted cookie for the token
try to minimize the chance of XSS (eg. by automatically scanning your code, but that will never be 100%, also by carefully choosing secure by default technologies)
make sure auhentication is based on the Authorize header and not the cookie
Still mainly because of the XSS risk, I would probably not recommend doing it this way in a security-critical application.
I was wondering if there is any relation between login and cross site request foregry ?
My question is, are there sites that have no login required but still require to be protected from CSRF ? Can you give an example
For CSRF to be effective, your site just needs to be able to act on behalf of someone in a way that doesn't require explicit authentication or validation.
Signed in users via auto-login cookies are the most popular CSRF attacks, but e.g. newsletter subscription forms may be just as vulnerable and can cause people to receive unwanted emails from your system to confirm their subscription.
So to answer your question, although login and CSRF are related, they are not exclusive to each other.
CSRF attacks exploit the authenticity of a client’s requests as an attacking site is able to forge requests that are executed by the client in behalf of the client and thus enjoy the server’s trust in the client’s requests. So the server assumes that any request from a client is intended behavior of the user that controlling the client. CSRF exploits this implicit trust.
At this point it is not necessary that the client is authenticated. Although authenticated users generally have special privileges that attacking sites are aiming for, the main goal of CSRF attacks is sending arbitrary requests in behalf of the user without their knowledge. So target sites can also be any site where you need a different originator than the attacking site (e. g. polls, unique visitors, malicious activities, etc.).