LocalStorage and Xss - xss

Can localstorage value of a site be overwritten by xss(cross-site-scripting)? As far as I have verified in chrome and firefox, the localstorage value of a site is not accessible by a different site. Can anyone tell me whether the localstorage value can be read/write from a different domain in the browser by xss ?

Nowadays many websites, add third-party js libraries for Analytic, A/B testing, Marketing tools, Heat maps and ... You may be sure about your codes but if one of these scripts, is vulnerable then you should expect XSS attack easily and in this case, It can grab your localStorage. Don't use local storage for session identifiers or sensitive tokens. Stick with cookies and use the HTTPOnly and Secure flags. To prevent CSRF attacks on Cookies, almost all requests include one or both of: Origin Header and Referer Header. CSRF can be partially prevented by checking the HTTP Referer and Origin header from your API. CSRF attacks will have Referer and Origin headers that are unrelated to your application.

Javascript coming from reflected XSS or similar can do whatever normal JS can do on the domain where the XSS exists. So if example.com has stored things in localStorage and example.com also has an XSS flaw, then that XSS vuln can be used to extract or overwrite users data in localStorage. You could even use a reflected XSS, which exploits a DOM-based XSS using data from localStorage, meaning a client side persistent XSS.

Web storage (local and session) follow single origin policy. So it XSS access to web storage is not possible.

Related

How does a xsrf token cookie protect against csrf?

Wouldn't a malicious site be able to read the cookie using xss cookie stealing and put it in the header of an ajax request?
Of course, if the site is vulnerable to xss, it's also vulnerable to csrf, but that's the smaller issue then.
If there is no xss though, the attacker has no way to read the token due to the same origin policy.

Security of storing Bearer token in cookies

My SPA uses React as front end and laravel API as backend.
When the user logs in (via axios and api), the api returns an access (Bearer token) as response. I use the react-cookie framework to store the access token as cookie in the Browser. This cookie will be read and used for any future request.
Is this the right way to do?
Isn't cookie data just something in the Browser that can be easily obtained by any attacker? Since it is just a file one the computer somewhere.
What is stopping an attacker from grabbing that cookie, impersonate as that user and start performing actions that requires authentication?
The token has a life span of lets say 1 year. It will only be refreshed every time the user logs in. I understand that if I set the life span shorter it will be more secure. However that will mean the user would have to log in constantly?
-----Update-----
Im not sure if any of the provided solution answered my question. A SPA app is front end based and the request can be from anywhere such as Postman, Mobile app, or any third party device that wish to talk to my backed server. So those device needs a way to store some access token locally to be used for any future request.
The only way I know this could happen is for my server to send some auth token to the requester and have it store it somewhere to be used for next request.
In this case, Im not sure if CSRF token or any other means would help my concern?
Just like facebook, if I clear my cache, I will have to re-login. That means facebook is storing something on my location computer so I can be automatically authenticated next time
I just want to add some disadvantages of storing tokens in cookies that you should also be aware of:
The max size of a cookie is only 4kb so that may be problematic if
you have many claims attached to the token.
Cookies can be vulnerable to cross-site request forgery (CSRF or
XSRF) attacks. Using a web app framework’s CSRF protection makes
cookies a secure option for storing a JWT. CSRF can also be partially
prevented by checking the HTTP Referer and Origin header. You can
also set the SameSite=strict cookie flag to prevent CSRF attacks.
Can be difficult to implement if the application requires
cross-domain access. Cookies have additional properties (Domain/Path)
that can be modified to allow you to specify where the cookie is
allowed to be sent.
------- Update -----
You can also use cookies to store the auth token, even it is better (at least in my opinion than using local storage, or some session middleware like Redis). And there are some different ways to control the lifetime of a cookie if we put aside the httpOnly and the secure flags:
Cookies can be destroyed after the browser is closed (session
cookies).
Implement a server-side check (typically done for you by
the web framework in use), and you could implement expiration or sliding window expiration.
Cookies can be persistent (not destroyed
after the browser is closed) with an expiration.
Your JS should not have access to the cookie. There are flags you can set on cookies that will help protect them and make sure they are only used for the correct purposes.
The HttpOnly flag is set on the cookie then JS will not be able to access it but it will still be sent with any request.
The SameSite flag will ensure that the cookie is only sent back to the site that gave it to you. Which prevents leakage.
The Secure flag will make it only send the cookie over a secured connection to prevent someone from sniffing it out of your web traffic.
Edit
You might want to lookup an authorization workflow but the gist of it is this:
User logs in with username and password
A JSON web token is issued upon login from the backend and sent to the browser
The JWT(JSON web token) can be stored in a cookie in the Web Storage(Session Storage) on the browser
Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization
Please see #tpopov answer as he also made some really good points.

Using JWT stored in HTTPonly & secure cookie: Vulnerable to CSRF. but not to XSS?

I understood webstorage is vulnerable to xss
And Cookie to CSRF also makes sense
What makes me puzzled is that it seems like implicitly said that cookie is not vulnerable to xss, but isn't it also vulnerable to xss?
If I can run a script on other's browser, I think I might be able to just send request to server & get important data cause browser automatically attach cookies & I dont' need to do anything to get authenticated.
If a cookie is set with the httpOnly flag, it cannot be accessed from Javascript (injected js cannot read or write such cookies), so it is not possible to steal the cookie value if it's httpOnly. This is very relevant for a session cookie. In this case, this cookie is not affected by XSS. Note that this is solely because of the httpOnly flag - cookies without httpOnly are affected by XSS, because they are accessible to Javascript.
Any cookie (regardless of flags*) will still be sent with any request to the server it was received from, but that is the realm of csrf, actually, it is the fundamental problem in csrf. If anybody (from any website) makes a request to a server, any cookie for that server will be sent, and the attacker can exploit csrf if there is no protection. That's why you need protection against csrf if you have cookie-based authentication.
Also note that if the page is vulnerable to XSS, than any csrf protection is useless, because xss can be used to read the token, wherever it is stored.
*Sidenote: the new SameSite cookie flag changes this, but that is only supported by Chrome.

CSRF prevention in browser plugin-only API that is available on HTTPS

I have to design an API that will support browser plugins only (latest version of Chrome, Firefox, IE). The API will be served over HTTPS. The API will be using a cookie-based access control scheme.
I am wondering what tactics to employ for CSRF prevention. Specifically, I want my API only to get requests from my own browser plugin itself and not from any other pages/plugins.
Would I be able to:
Assume that in most cases there would be an Origin header?
Would I be able to compare and trust the Origin header to ensure that the requests only come from a white-listed set of Origins?
Would this be compatible across the board (Chrome/Firefox/IE)?
I'm aware of multiple techniques used to prevent CSRF, such as the Synchronizer Token Pattern, but I would like to know in my limited scope above, if simply checking the Origin header would be sufficient?
Thanks in advance!
Set a custom header like X-From-My-Plugin: yes. The server should require its presence. It can be a constant. A web attacker can either:
make the request from the user's browser: this sends the cookie, but they can't send the custom header cross-origin; or
make the request from a different HTTP client: they can send the custom header, but they can't send the cookie because they don't know it
Either way, the attacker's request won't have both the cookie and the custom header.

Are JAXRS restful services prone to CSRF attack when content type negotiation is enabled?

I have a RESTful API which has annotations like #Consumes(MediaType.JSON) - in that case, would the CSRF attack still be possible on such a service? I've been tinkering with securing my services with CSRFGuard on server side or having a double submit from client side. However when I tried to POST requests using FORM with enctype="text/plain", it didn't work. The technique is explained here This works if I have MediaType.APPLICATION_FORM_URLENCODED in my consumes annotation. The content negotiation is useful when I'm using POST/PUT/DELETE verbs but GET is still accessible which might need looking into.
Any suggestions or inputs would be great, also please let me know if you need more info.
Cheers
JAX-RS is designed to create REST API which is supposed to be stateless.
The Cross Site Request Forgery is NOT a problem with stateless applications.
The way Cross Site Request Forgery works is someone may trick you to click on a link or open a link in your browser which will direct you to a site in which you are logged in, for example some online forum. Since you are already logged in on that forum the attacker can construct a url, say something like this: someforum.com/deletethread?id=23454
That forum program, being badly designed will recognize you based on the session cookie and will confirm that you have the capability to delete the thread and will in fact delete that thread.
All because the program authenticated you based on the session cookie (on even based on "remember me" cookie)
With RESTful API there is no cookie, no state is maintaned between requests, so there is no need to protect against session hijacking.
The way you usually authenticate with RESTFul api is be sending some additional headers. If someone tricks you into clicking on a url that points to restful API the browser is not going to send that extra headers, so there is no risk.
In short - if REST API is designed the way it supposed to be - stateless, then there is no risk of cross site forgery and no need to CSRF protection.
Adding another answer as Dmitri’s answer mixes serverside state and cookies.
An application is not stateless if your server stores user information in the memory over multiple requests. This decreases horizontal scalability as you need to find the "correct" server for every request.
Cookies are just a special kind of HTTP header. They are often used to identify a users session but not every cookie means server side state. The server could also use the information from the cookie without starting a session. On the other hand using other HTTP headers does not necessarily mean that your application is automatically stateless. If you store user data in your server’s memory it’s not.
The difference between cookies and other headers is the way they are handled by the browser. Most important for us is that the browser will resend them on every subsequent request. This is problematic if someone tricks a user to make a request he doesn’t want to make.
Is this a problem for an API which consumes JSON? Yes, in two cases:
The attacker makes the user submit a form with enctype=text/plain: Url encoded content is not a problem because the result can’t be valid JSON. text/plain is a problem if your server interprets the content not as plain text but as JSON. If your resource is annotated with #Consumes(MediaType.JSON) you should not have a problem because it won’t accept text/plain and should return a status 415. (Note that JSON may become a valid enctype one day and this won’t be valid any more).
The attacker makes the user submit an AJAX request: The Same Origin Policy prevents AJAX requests to other domains so you are safe as long as you don’t disable this protection by using CORS-headers like e.g. Access-Control-Allow-Origin: *.