It's not a zero-sum situation. There are risks and vulnerabilities in every approach, that's why we as web devs take advantage of multiple safeguards to ensure safety when sensitive information is to be transmitted over the wire.
As sibling comment says, this is what SameSite is for.
If it's a POST form, SameSite=Lax or SameSite=Strict won't send the cookie.
If it's a GET form, SameSite=Strict won't send the cookie. SameSite=Lax might, I'm not entirely sure.
However, with cookies, you have to be careful with the SameSite flag and also be mindful that some older browsers may not support it and so it can be tricky to fully restrict where the cookie will be sent in all scenarios.
localStorage is totally accessible to any JavaScript running on the page, so your session can be completely hijacked and used later.
Not completely true - the attacker can not exfiltrate the token but they can still make malicious requests right there in the victim's browser via XSS.
If you can inject javascript, it's game over anyway.
> HTTPOnly cookies are safe from XSS attacks.
No, you can still do pretty much anything that cookie enables you to do. You just can't get the actual cookie string.
Yeah, but as you pointed out the one thing you can't do is get the cookie. Having the auth token yourself as the attacker is a way different story then just having XSS vulnerabilities. You can still "do" a lot, but you still have to get another user with the token you want to interact with the page with your XSS to "do" what you want.
You need to do this in both cases.
Upon access token refresh and login, refresh token is also rotated.
Refresh token expiry is tens of days, access token some hours.
Their opinion is that this is enough security.
IMO refresh token is vulnerable being stored in localStorage, and relying on users logging in and/or triggering token refresh to rotate refresh token is not really that great.