How to handle OAuth Client_Secret in Pebble app - a proposal

I have a working Pebble app which allows turning on and off of SmartThings devices. That part works fine. Now, I’m working on the initial OAuth-2 code for acquiring an initial Token and handling the refresh token (Tokens expire in 24 hours). My JS code can currently open the initial web page, acquire the Code, and use that Code to acquire a Token.

Here’s the issue. I can’t put my Client_Secret directly into the JS code, because we all know that JS code is easily visible to anyone who has the .pbw file. I thought about putting it into the C code, xor’ed with some value, then decrypting it in C and passing it over to JS via messaging, but I’m informed that people could also snoop on watch->phone messaging by simply inserting a little code into the JS part of the executable. (I would have thought there would be a hash on this, but perhaps that can be recalculated and inserted as well, I don’t know.) I’ve read that the real way to handle this is to send your token request to a 3rd party server, which will insert the client_secret, pass it on, receive the reply, and relay that back. I have my own web server, so I could do this.

Here’s my proposal:

  1. If we do not have a Token, then use the “showConfiguration” event in the JS code to contact SmartThings where the person can login, accept the scopes needed.

  2. The Code will be returned to the JS code via the “webviewclosed” event.

None of the above requires a Client_Secret, only the Client_ID. Note, the interaction (1) is a two way interaction between SmartThings and the user, so it can’t be filtered through a backend server as will be done in step (3).

  1. Send the Code and Client_ID to a special web page on my server to acquire the Token.

  2. This special web page will insert the Client_Secret, put together the message to acquire the Token, and reply to the query (3) with the Token, Refresh_Token, etc.

From here, onward, no Client_Secret is needed, just accesses using the Token and refreshing the Token using the Refresh_Token.

Yes, anyone could send a request to the special code (step 3) and have my Client_Secret added, etc., but they wouldn’t have a valid Code unless they snooped on the interaction (2), but if they have that, then why would they be doing this? I guess they could technically make use of my Client_ID and the appended Client_Secret, to have the Token assignment count against my app instead of their own. That’s the only motivation I see, and it’s not much, since anyone can get their own Client_Secret for free from SmartThings.

Thoughts?

1 Like

Thta sounds reasonable. I would also send the app UUID with your request so that you can handle OAuth for different apps you make separately. And yeah there’s no check for the JS code tampering. The nice thing about it is that it makes it very easy to patch API calls if something uses a deprecated service. But the downside is that there’s no way to do integrity checks

2 Likes

The JS code would be already passing the Client_ID to the backend server in step (3), so that program could easily match it against a table and insert the appropriate Client_Secret for that app.

1 Like

Ah, good point. I missed that

1 Like