It's ignorance of Origin.
I've been ranting about cookies before, but now realized the very general flaw of cookies: they ignore Origins.
Origin = Protocol (the way you talk to server, e.g. http/https) + Domain (server name) + Port. It looks like http://example.org:3000 or https://www.example.org
Obviously, cookies is the only adequate way to authenticate users.
Why localStorage is not for authentication? it's accessible on client side thus authentication data can be leaked + it's not sent on server side automatically, you need to manually pass it with a header/parameter.
Origins made web interactions secure and concise:
localStorage from http://example.com can't be read on http://example.com:3000
DOM data of http://example.com can't be accessed on http://example.com:3000
XMLHttpRequest cannot load http://lh.com:4567/. Origin http://lh.com:3000 is not allowed by Access-Control-Allow-Origin
Cookies got 99 problems, and XSS is one.
2) "protocol" and Cookie Forcing problem.
People were aware of MITM and they restricted sending "https" cookies to "http" - great!
They didn't restrict sending "http" cookies to "https" - oh shi~. Cookie forcing leads to cookie tossing easily and cookie tossing leads to user owning pretty easily as well.
Tip: Store csrf_token inside of the session cookie (literally) and refresh it after login.
3) The "port" thing.
This is not a solved problem yet. If someone owned a ToDo-App at https://site.com:4567 he will get all the cookies for https://site.com with every request. Yes, "httpOnly;". Yes, "Secure;" too. Cookies just don't care about ports.
How can we fix cookies?
1) Don't let Ports share cookies - make browsers "think" that port is a part of a domain name.
2) Origin field. Set-Cookie: sid=123qwe; Origin=https://site.com:4567/; will mean "Secure;", "Port=4567" and "Domain=site.com" at the same time.
During last decade many workarounds were introduced only to make cookies more sane, yet not implementing straightforward Origin approach. We are doomed to maintain it forever...?