I sometimes use web storage(sessionStorage) to store temporary data when I build SPAs.
(I know I shouldn’t store any sensitive information in web storage)
Web storage can restrict to access its data by same-origin policy, which means if I’d like to restrict it for security reasons, I have to use an another (sub)domain, which seems to be costs for developers.
If a site has XSS in a page of its domain, all stored data in web storage can be stolen like this.
[...new Array(1000)].map((_, i) => localStorage.key(i)).filter(k => k).forEach(k => console.log(k, localStorage.getItem(k)))
[...new Array(1000)].map((_, i) => sessionStorage.key(i)).filter(k => k).forEach(k => console.log(k, sessionStorage.getItem(k)))
In addition to that, web storage can’t specify expires to the data so it;s difficult to store only necessary data.
So I think it would be nice if web storage has a feature that is able to restrict to access its data by path or expires as well as Cookie.
The same might apply to IndexedDB.
Are there already any discussions about this?
I’ve found it.
Alternatively, should I just use CSP?
Why should you not store any sensitive information in local storage?
If you limit access based on path, you only need to XSS on the right path, and if by cookie, you can XSS and steal the cookie too. So I think this only creates an illusion of security. A strong CSP should block most (all?) XSS vectors.
Because all stored data can be stolen if a page in same domain has an XSS.
OWASP recommends not to store sensitive information in local storage.
You are right.
But We need to apply CSP in all pages in the same domain to block to this by CSP, don’t we?
If I’m developing an app on
example.com/apps/a/ and use web storage to store some data and apply CSP to the app, I can protect the data from XSS.
example.com/some/page.html has an XSS which is maintained by others, the data can be stolen from the XSS.
To avoid this, I need to host the app on an another domain.
I can protect the data If I could store data with restriction by path.
The same-origin policy is a critical part of browser security. If you host other people’s content on the same origin and you don’t trust them to properly secure their content, then moving your content to a different origin is the correct thing to do IMO.
+1 to that - finer-than-origin security boundaries for web content are not reliable, and don’t even exist in many of the APIs (e.g. permissions, web storage, HSTS.) If expiration time is the main worry, though, you could consider encrypting the stored data using crypto.subtle and storing the decryption keys in expiring cookies. And yes, you can path-scope the cookie, but that’s not actually particularly helpful security-wise as there are a number of ways pages in other paths can coerce arbitrary different sub-paths into acting on their behalf, including IFRAME-and-script. Preventing all such same-site scripting vulnerabilities is AFAIK basically impossible and most current security work on the web is aimed at origin-granularity rather than origin+path-granularity as the smallest defensible perimeter
Thank you for your answers!
I understand the path restriction doesn’t work well on the web because of iframe + XSS.
The same-origin policy is a critical part of browser security.
I agree with you.
In particular, I think the same-origin policy is a more important topic on the web because the web will be HTTPS everywhere.
It causes to make unexpected pages as the same origin.
To avoid to stolen web storage data stored by an app, we can choose these options
- Isolate the app by the same-origin policy
- Apply CSP everywhere in the domain
Are there any other options or proposals?