TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Web Storage: the lesser evil for session tokens

195 点作者 kkl将近 9 年前

16 条评论

tptacek将近 9 年前
I&#x27;m worried that people are confusing what Kettle is saying in this post.<p>He&#x27;s <i>not</i> saying that XSS protections don&#x27;t matter because attackers &quot;prefer&quot; CSRF over XSS. They do not.<p>What he&#x27;s saying is that pages that are vulnerable to XSS attacks --- or, properly: pages that are vulnerable to Javascript injection and DOM corruption --- open up a wide vista of exploits, and &quot;stealing session tokens&quot; is just the most naive of them.<p>Many of the more sophisticated exploits for Javascript injection resemble CSRF. But I think it&#x27;s a little confusing to overload the term that way: Javascript-injectors have more latitude than conventional &quot;blind&quot; CSRF attackers do.<p>Long story short: once you&#x27;ve lost control of the Javascript on a page in your same-origin, you&#x27;re almost always toast. Attackers can hijack sessions. That they don&#x27;t store and retain the token is irrelevant; the token is just an artifact.<p>I don&#x27;t know anybody who works full-time in software security who thinks HttpOnly is a meaningful defense, but, if you&#x27;re out there, chime in and make a case for it. :)
评论 #11810208 未加载
评论 #11810040 未加载
评论 #11809534 未加载
avolcano将近 9 年前
It&#x27;s funny, I got started with web development relatively recently (2012 or so) and immediately started working on single-page&#x2F;client-side applications, so I used localStorage from the start. It seemed easy enough to make a little Ajax wrapper for all my requests to tack the authentication token on (whether as a URL param, form data, or header data).<p>Imagine my surprise when I later learned how cookie storage worked! There was a brief moment of &quot;oh, I guess not having to manually append this to my requests would be nice,&quot; only to read about CSRFs and other horrors cookies enabled.<p>Since then, I&#x27;ve fixed multiple existing CSRF exploits in production (or near-production) applications, and continued to avoid cookies wherever possible.
评论 #11808570 未加载
评论 #11808842 未加载
评论 #11810075 未加载
zoomzoom将近 9 年前
The overall gist here seems to be that XSS is not anything to worry about because if there was an exploit the attacker will always choose CSRF. However, there are well-understood and proven mitigation strategies for almost all versions of CSRF attacks. For XSS you are reliant on a CDN or your own code review of your hosted JS to prevent all XSS. I&#x27;m not willing to bet I&#x27;ll never make a mistake like that. An XSS can expose a lot of users very quickly in that scenario, and the mitigating factor usually offered is some time-expiring attribute of the tokens stored locally, but for usability reasons such expiration is usually long enough that an attacker will have plenty of time to use the tokens. Http-only secure cookies provide strong mitigation here that covers more scenarios.<p>In general, it&#x27;s annoying because local&#x2F;session storage are so close to being ready for prime-time, and as outlined here there are various advantages. But the XSS mitigations are too important to abandon if you really want the most security available, IMO.
评论 #11808721 未加载
dcosson将近 9 年前
These are all good points, but ultimately it seems like a well-configured cookie-based storage is equally secure as a similarly well-configured web storage session. There are more hacks required with cookies, but you hopefully only have to configure them in one place and there are libraries to help with the tricky parts like CSRF mitigation.<p>OTOH, there are some usability issues with web storage. Mobile safari in private mode (which can be a not-insignificant percentage of iOS traffic) doesn&#x27;t support localstorage. Also, if you have any server-rendered pages, say, you have both a single-page web app and some admin pages with server-rendered html content, you need cookies anyway for the server-rendered pages (unless you want to make all your non-ajax forms to submit via ajax to use the local storage token, which is a pain because you&#x27;ll end up fighting against most web frameworks and re-inventing the wheel).<p>Given this, my takeaway is that cookies basically cover a super-set of the scenarios that local storage tokens do, so it seems preferable to stick with cookies everywhere vs. using two separate auth flows, even though I agree that web storage is conceptually a nicer model with a smaller attack surface.
评论 #11811934 未加载
评论 #11812023 未加载
somlor将近 9 年前
For single-page apps I use <i>two</i> session tokens. One in localStorage (csrf_token), one in a secure, HttpOnly cookie (auth_token). Both tokens are required for the API to authenticate a request.
评论 #11807803 未加载
omgitstom将近 9 年前
As a developer, I feel like I have more control over mitigating CSRF then XSS.<p>But where I have more issues is that OWASP clearly advises not to use web storage for identities:<p>+ A single Cross Site Scripting can be used to steal all the data in these objects, so again it&#x27;s recommended not to store sensitive information in local storage. + A single Cross Site Scripting can be used to load malicious data into these objects too, so don&#x27;t consider objects in these to be trusted. + Pay extra attention to “localStorage.getItem” and “setItem” calls implemented in HTML5 page. It helps in detecting when developers build solutions that put sensitive information in local storage, which is a bad practice. + Do not store session identifiers in local storage as the data is always accessible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.<p><a href="https:&#x2F;&#x2F;www.owasp.org&#x2F;index.php&#x2F;HTML5_Security_Cheat_Sheet" rel="nofollow">https:&#x2F;&#x2F;www.owasp.org&#x2F;index.php&#x2F;HTML5_Security_Cheat_Sheet</a>
评论 #11808984 未加载
评论 #11810331 未加载
评论 #11810619 未加载
sly010将近 9 年前
It absolutely makes sense for large single page applications where you are doing multiple roundtrips to load the application anyway and you will keep the tab open (e.g gmail &#x2F; trello &#x2F; etc).
评论 #11808726 未加载
albinowax_将近 9 年前
Let me know if you think it&#x27;s all wrong :)
评论 #11807625 未加载
评论 #11807545 未加载
vladgur将近 9 年前
I would agree that Session storage is an ideal way for handling your session token if it wasnt for the fact that its only visible in a current window&#x2F;tab.<p>I do want my users to be able to keep their session across tabs and not be forced to sign in again and as far as I know the only way to do this is to use cookie storage<p>Does anyone have a strategy use one of Web Storage APIs AND keep your session across tabs&#x2F;windows?
评论 #11809233 未加载
advisedwang将近 9 年前
My concern with a Web Storage based token is additional latency. With this system, a page has to be served, javascript executed, and an XHR sent before an authenticated response can be sent. With Cookies, the very weakness the author points out - sending it on the first HTTP resonse - is a massive asset for reducing latency.<p>Is there a way to mitigate this?
评论 #11808727 未加载
评论 #11808088 未加载
therealmarv将近 9 年前
Very newbie question but is this always true? &quot;Another distinction is that sessionStorage will expire when you close the tab rather than when you close the browser&quot; So I cannot use session tokens in the same way as (secured) cookies for letting the user e.g. logged in when all tabs closed?
评论 #11808118 未加载
hoodoof将近 9 年前
OK so I am just about to write some code for storing tokens.<p>What is the definitive answer for where I should store them? Based on this blog post, the answer seems to be &quot;Web Storage&quot;
评论 #11811823 未加载
andersonmvd将近 9 年前
Although it&#x27;s true that tokens in localstorage doesn&#x27;t expire, the token itself can expire if you set it to expire when using Json Web Tokens (JWT) for example.
ninjakeyboard将近 9 年前
isn&#x27;t this sort of a use-case-specific choice? for unsecure data you can sign it and put it in a token as a cookie eg JWT. Different use cases will support different approaches and have benefits and draw backs. The more state you put in the browser, the less you have in your app. That can be better or worse for many reasons - simplicity, performance, scalability etc are all impacted.
awinograd将近 9 年前
I definitely agree with the premise that cookies are inherently insecure. With sessionStorage it&#x27;s unclear to me if there&#x27;s a clean way to send the secret with every http request. Does that mean binding to every link &#x2F; button click event?<p>Also you mentioned this, but disappearing on tab-close makes it less of a drop-in replacement for cookies since that breaks existing behavior.<p>Interesting idea though! Enjoyed the read.
评论 #11807613 未加载
pfooti将近 9 年前
I&#x27;ve been doing a fair bit of web app development (single-page, CMS like stuff with user-generated content in the vein of a wiki, forum, or adjacent use space). I keep my session tokens in localstorage, websql, or indexeddb (depending on the platform, [0] is a really nice polyfill &#x2F; shim to give you good key-value stores on many different browsers).<p>My session tokens are just 48 characters of base64 randomness, because that way I don&#x27;t have to worry about dealing with JWT - it&#x27;s a neat idea, but there have been enough bugs in the implementation that I&#x27;m still leery. Plus: this way I can expire tokens on the server side.<p>I keep session tokens stored in redis, and do an expire on them by default. Each time the token is fetched, it gets expired again (so the token actually expires N days after the last time the user visits). So yeah, each API request is burdened with two redis calls - one to verify the token and another to reset exipiry. It doesn&#x27;t seem to weigh on my overall server perf - the actual API call is where most of the cpu goes (relatively speaking, it&#x27;s still straightforward indexed sql queries most of the time).<p>The token is attached as a bearer token in the header of all my XHR requests.<p>The big problem is images. I work with teachers, who may want to post images of students or student work (to share with colleagues in a research project, behind security is okay, but not if those images can leak to the broader world). You can&#x27;t (AFAIK) set browser-wide headers on the request that gets generated when the browser encounters an img src=&quot;url&quot; tag. That&#x27;s unfortunate, and I&#x27;ve played with a few options. One is: don&#x27;t protect images at all - if the images aren&#x27;t sensitive, then leaking them to twitter or pinterest when a user right clicks isn&#x27;t the end of the world. One is: use a cookie that&#x27;s only good for authenticating on the image server, and set it at app init time. One is: fetch the image data in an XHR, set the image up as a blob in the page, and set the img src attribute to the blob&#x27;s dataurl.<p>None are particularly satisfying. You can crash the chrome tab (at least in chrome, I didn&#x27;t test in safari &#x2F; ff once I knew I was crashing chrome) if you go with the blob direction if the blob image is too large (goes OOM, then goes &quot;aww snap&quot;). Unfortunately, the blob approach is probably the best one if you&#x27;re really worried about leaking images due to user foolishness - any user could download and re-upload an image anywhere, but you want to prevent someone from right-click, copy-image-url, tweeting the image. The blob approach prevents the image url from leaking in that situation, whereas the special-cookie approach doesn&#x27;t.<p>Ultimately: we decided that we would allow images to leak if they had to - we&#x27;re training users that they need to not embed potentially sensitive images inline at all. It&#x27;s annoying, but there we are. Here&#x27;s where session storage doesn&#x27;t work as well as cookies.<p>0: <a href="https:&#x2F;&#x2F;mozilla.github.io&#x2F;localForage&#x2F;" rel="nofollow">https:&#x2F;&#x2F;mozilla.github.io&#x2F;localForage&#x2F;</a>