4 ms·
I'm still not entirely clear on if I should abandon implicit flow for a static site to get credentials. Easy enough to switch it to the CODE flow, but that get
by taeric 2y ago
I'm still not entirely clear on if I should abandon implicit flow for a static site to get credentials. Easy enough to switch it to the CODE flow, but that gets you a refresh token with AWS and that feels a bit more risky to have on the client side.
- candiddevmike 2y agoYou (typically) only get a refresh token if you ask for offline access in your request scope AFAIK. It's not the default (online is).
- taeric 2y agoFor AWS Cognito's Token endpoint? Where is that documented? I'm also not seeing that behavior, as I don't have that in my scope and I do get a refresh token if I do the CODE flow.
- candiddevmike 2y agoI'm referring to the openid standard I guess[1], it looks like AWS Cognito does something different (they don't support offline_access, but they always issue a refresh_token from what I'm reading). 1 - https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess https://openid.net/specs/openid-connect-core-1_0.html#Offlin...
- taeric 2y agoYeah, if you do a CODE flow, you get three tokens. Implicit is only access. They at least have decent support to guard api access using these.
- CuriouslyC 2y agoYou can do stuff to keep the lifetime down on the refresh token.
- taeric 2y agoI mean, sure. I can also revoke them and such. Still not clear if that is much better than just doing the implicit flow.
- littlecranky67 2y agoProblem is that Cognito impicit flow wont issue refresh tokens and limits acces token lifetime to 24h
- taeric 2y agoRight, but that seems preferable if I'm doing this all client side? Yes, an access token could get leaked in the URL. But sending the refresh token to the client feels far more dangerous.
- littlecranky67 2y agoYeah but that also means your users will have to re-login every 24h. Other implementations (i.e. Keycloak) issue refresh tokens on the implicit flow.
- taeric 2y agoIs it ok practice to store the refresh token in local storage, then?
- littlecranky67 2y agoI think that is the only way to do it if you use any openID connect implenmentations - which is often my criticism about it. Modern browsers can have cookies using SameSite=strict and HttpOnly cookies, which I would consider better than storing refresh tokens in localStorage or even expose them at all to javascript. But OpenID Connect predates those browser features, so everyone seems okay with it.
- mooreds 2y ago> I'm still not entirely clear on if I should abandon implicit flow for a static site to get credentials. The answer is to threat model. What's the risk of an access token falling into the hands of someone who has got malicious JS into your webpage? If it is a public API or not risky, maybe implicit is okay. There's more on the attacks and mitigations here: https://fusionauth.io/blog/whats-wrong-with-implicit-grant https://fusionauth.io/blog/whats-wrong-with-implicit-grant
- taeric 2y agoMy point is implicit or code, the tokens are on the client. And if code, refresh tokens will be there, too. If malicious code on client is a big risk, I really don't see how the flow matters at all. Specifically if the only computer I have is on the client.
- mooreds 2y agoThere are a couple of ways to keep tokens on the client that prevent malicious code from accessing them. - use HTTPOnly secure cookies. These will not be accessible to malicious JavaScript but can only be sent to servers on the same domain. Well, I guess if there was an exploit that let JS break the sandbox and access cookies, they could be accessible, but I think we can trust the browser vendors around this kind of security. This approach is widely supported, but does expose the token to physical exfiltration (that is, if someone on the browser opens up devtools, they can see the cookie with the token in it). - store the tokens in memory. As far as I know, malicious JS code can't rummage around in memory. This works for SPAs, but does break if the user refreshes the page. - bind the token to the client cryptographically using DPoP. This is a newish standard and isn't as widely accepted, but means you can store the token anywhere, since there's a signing operation tied to the browser. All of these can work and have different tradeoffs.
- taeric 2y agoI can't use http only cookies, because I have no server to set them. I'm using JavaScript on the client to do the post to get the tokens. Storing in memory is mostly fine, though I do want them in a cookie. May be able to skip that. I will look into the dpop thing. A bit limited as I'm using AWS cognito. I confess my thread model is such that I think I am fine with storing token in local storage. Would like to be using standard practice, though.
- apitman 2y agoThat's an interesting question, but what exactly is the threat model here? A rogue extension somehow reading the token? Is it stored anywhere? AFAIK generally the concern with access tokens is that they get gleaned from logs or MITM, not pulled out of the browser's memory.
- taeric 2y agoSure, but there are also good habits? I get not having the token in the url is a logs protection. I'm less clear on storing it in local storage.
- apitman 2y agoI'm not sure we're talking about the same thing. Basically I'm saying that generally the URL bar and logs are considered more vulnerable than variables in memory. However, I think I would trust a value that's been transmitted from memory more than one that's been stored in localStorage but not transmitted, because the latter is trivial to grab with an extension. I'm not aware of any way for an extension to grab a variable from memory unless it knows how to access the variable itself from JS. This makes me wonder if there could be a security practice where you purposefully only store sensitive data like OAuth2 tokens in IIFEs in order to prevent extensions from accessing them. There's got to be some prior art on this. Anyway, thanks for bringing up the question. It's been a useful thought experiment.
- taeric 2y agoMakes sense and I agree there. The code flow has the advantage of not being in the url. I'm still unclear if I have a best practice on how to store the refresh token on a static website client. Feels off using local storage.
- apitman 2y agoIf you're in a situation where you would otherwise be using the implicit flow, can't you just throw the refresh token away? That should approximate the implicit flow.