OAuth Token Revocation

Continuing the discussion from Changes for OAuth Access Token Requests:

What’s the story with OAuth token revocation? I cannot find any documented way to revoke previously issued OAuth tokens. It’s a serious security issue if tokens cannot be revoked. It pretty much defeats the purpose of using OAuth.

Also, RFC 6749 recommends that tokens be revoked if authorization code is used more than once. Please correct me if I’m wrong, but I don’t think SmartThings follows this recommendation.

4.1.2. Authorization Response

If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code.

10.5. Authorization Codes

If the authorization server observes multiple attempts to exchange an authorization code for an access token, the authorization server SHOULD attempt to revoke all access tokens already granted based on the compromised authorization code.

2 Likes

Delete smartapp installed instance and token is revoked. Best one can do right now. Each instance gets new token, and I think there was a command to issue new token, but don’t remember if that revokes old token?

Well… I guess it’s not as bad as advising someone to sell their house after they’ve lost their keys, but it’s clearly not how OAuth tokens are supposed to work. Besides, deleting the app that has dozens of connected devices and took hours to set up and configure may not be as easy as it sounds.

Irrevocable tokens combined with 50 years expiration term is definitely a security risk, imho.

1 Like

I don’t know if the same mechanism is used (probably is?), but the token granted when you log into the Mobile App also doesn’t seem to ever expire … even if you change your password via another mobile device or the graph.api website.

I find this latter detail particularly worrying because most people assume that if you change your password that would be sufficient to prevent someone who has stolen your phone from using your SmartThings. Unfortunately, not true, as far as I can tell.

1 Like

I remember smarttiles having that capability. You may want to ask @625alex for help with implementation.

1 Like

SmartTiles simply keeps a list of “revoked” tokens and checks the access token against this list. It essentially implements blacklist at the application level.

Eww. :cold_sweat:

Well… very kind of @625alex to including that feature in the SmartApp.

Unfortunately token revocation for app level endpoints is insufficient as that method still allows access to the state of the application, which might contain sensitive data.

I am going to send support an email describing this as a security bug, I encourage anyone interested in token revoking to do the same.

Also, in regards to the OAuth2 spec, which I am not super familiar with, I believe the authorization code (single use) is different from the token (multiple use), I am not aware that SmartThings actually supports multi-leg OAuth to the SmartThings service.

1 Like

Also it looks like the state is not accessible by a token, either that issue has already been fixed or I was wrong in thinking that it could ever be.

Not sure what you mean…?

SmartApps can expose mapping Endpoints that return any arbitrary data including “state.*, but the SmartApp itself can only read/write the Things that are authorized by the user / token.

What it means is that ‘state’ is always exposed as HTTP endpoint, without explicitly declaring it in the ‘mappings’ section.

2 Likes

Ah… Thanks.

That doesn’t see like a very good idea. Is it documented? Is there a good reason??

1 Like

I don’t think it’s documented and it’s definitely not a good idea because it exposes all internal state variables to the web client without explicit authorization.

1 Like

My guess is that the state endpoint exists for the mobile app to use, I think I found that endpoint by curiosity rather than anything in the docs. Might be able to find others by brute force or doing a mitm or debug on the mobile app.

I have made a rather important assumption that the mobile App uses an entirely different API than the one we have access to.

There are good reasons for and against this design, so I don’t know why I assume this.

One reason is that dashboard code like @625alex 's http://SmartTiles.click does not have as complete access to UI APIs, obviously… So…?

Perhaps @Ben or @tslagle13 can confirm or correct me.

I don’t think it’s a secret. This is known as ‘core’ API and is not available to mere mortals, although unofficial API doc has been out there since 2013. :smile:

2 Likes

Yup… that’s fabulous information. I can’t believe the URI’s still work.

Oh well… might as well “enjoy”.

It’s actually other way around. SmartTiles keeps one white-listed token.

1 Like

Revoking tokens used to work until it didn’t, so I had to encode this workaround.

1 Like

Actually the old token capability to access state is still an issue when using alternate methods rather than the URL path. For instance adding the token to the params in the URL works:

https://graph.api.smartthings.com/api/smartapps/installations/XXX/state?access_token=YYY

The above is accessible, however the following URL is safe:

https://graph.api.smartthings.com/api/token/YYY/smartapps/installations/XXX/state

So the app generated token does not allow access to the state for /api/token endpoints but params do.

Then currently, even with a white listed token on app endpoints an attacker might be able to use an old token to gain the current token, or any other secret state information living in the state.

1 Like