Putting Access_Token to rest - inside the core - Most Secure

@bko, @BDub, @Zach, @kennethlimcp,

Hi guys,

Not to get off topic which is, “Access_Token Security”, I come to you today as I can’t find one word on docs.spark,io about “access_token” security and I have to ask; why not ?

Let me make an uneducated rational estimation of why, because there is no set “official recommended” absolutely secure method being promoted, that’s why. I am not the expert and that is why I opened this thread.

Nor can I find any information in docs or forum about how to make a secure connection to control the core without the cloud even though people are being told how to turn the Coud off.

Others have said to use a PHP Proxy server to hide the access_token in an HTML page but, most people will lack the skills to impliment such a scheme.

Others have suggested using a Secure Webage and I am really for that too using Aapache Password webpages but, that does not address the issue of passing a person’s real access_token number accross the web.

To resolve this security issue for both Cloud & non-cloud use, there needs to be a common security method.

Why not place the access token in the core ? (My examples are below). Then use Cookies to set the user secure connection like Paypal & Ebay & all banks use. ?

My Examples:

I can set a jQuery variable for the Access Token in the IDE like this:

< script> $(document).ready(function(){
{
accessToken = “e2cec1f4d656c5595091935095f593f0fec135e3”;
}
);
< /script>

Then “In IDE” I use this HTML to change a Pin on my core:

webClient.println("{ args:“D0,HIGH”, access_token: $access_token })};< /script>< /p> \n\n");

But, what is needed is a way to set a Spark.Variable=" access_token" like this ?

Spark.variable(“e2cec1f4d656c5595091935095f593f0fec135e3”, access_token, STRING);


I am sure there are ways of using MD5 hash along with the cookie scheme so the user connection is “Absolutely Secure” and the access_token never gets broadcasted via the web.

What do you guys say ? Do you not feel this needs to be addressed and people should have the best method that can be used for both cloud and non-cloud acess; becasue the later will eventually happen.

Thanks for your time and consideration,

Bobby

Hi @spydrop Bobby

I am not sure I am seeing the whole picture. You seem to be saying, by analogy, that by locking my keys inside my car, I should always be able to start it. But now I don’t have a way to get in the car in the first place!?!

The access token is a key that you rent (it expires) that lets you talk to your cores over the cloud and is the way the cloud knows it is you, no matter where you are coming from. There are a bunch of ways to rent that key described in this doc section:

http://docs.spark.io/api/#introduction-authentication

Hi @bko,

Yes, I know the access_token is the key to the “Cloud” to access the core and why did someone else make the decision that I have to get new keys to my car from time to time ? Why is that ?

Why not allow the user decide when he needs to change the locks on his car ? (I Know why, later in post)

Its a key but, your anaolgy does not really represent the issue at hand. Its more like a combination lock and are you going to right it on the lock ? That better represents the problem at hand.

Let me be absolutley frank about where I am coming from. Since the offical way to use the Spark Core Access token is to transmit the real token number across the web, its not hackers that I worry about ! Should I just call up AT&T and give them my access_token number and ask them for a cut me in on the profits when they sell it ?

Sure, this example is an extreme but, what if its a hacker and my spark core controls the lock on my safe where I keep the Magic Golden Egg from the Magical Golden Goose. I can assure you that Goose wants me to never give the code or access_token number to that safe to anyone who would still her Golden Egg !

Its an easy fix using MD5 Hash / Cookies and a Https Link and the core access token is safe on the core and will work for both Cloud and local access.

Again, why do I have to change the access_token ? Because the way its being handled at this time is not safe; never will be as designed. Why Is that ?

Did you know that all encyrpted devices must have a backdoor password and such password must be given to the United States Department of Justice prior to selling such encryption / encripted device in the United States ? Is that a better analogy of why the cloudl is not secure ?

I am just looking for a better way to secure my core while using the Cloud and that would be by not transmitting the access_token via the web.

Am I wrong ?

What other method is avaiable to command my spark core that does not expose my access_token to the web ?

Thanks, Bobby

The cloud API only accepts HTTPS connections so your access token is always transported encrypted.

The issue is if you want to have a web page on a server on the Internet, you need to take steps to prevent someone from doing View Source on your web page to see the token. These steps are easy if you have your own web server and could be automated at the level of a pop up dialog asking for your username and password which would use the HTTPS Cloud API to fetch a new access token and store it securely on the server.

These steps to prevent your token being visible are harder or impossible if you are just serving up a static page from a web hosting service that doesn’t allow server side programming.

I think cookies really don’t apply here since the traffic is server to server, not browser to server.

1 Like

Yes, I agee 100% with you on https api connections.

To obtaing a https: connection and send “access_token” via API HTTPS Securely I would need to either:

Use Putty Terminal (https)to run Curl GET Commands.

Build a Java API application (Https:)

or as you say, have my host account include a https connection. The build server side scripting to keep access_token safe beyond file permissions and Apache Directory Password Protection.

You Know, I have never had to do this before with any MCU device or CMS portal to secure a password.

The abstract of all of this, if I may, is the API requires a HTTPS connection that most people will not be able to facilitate on their webpage / hosting account ($$) or by using a terminal program like Putty or be able to build their own Java Android application (Most people are hobbyist - not programmers).

@bko, However, you alluded to a fact that I did not consider. It would be just as easy for Spark Team to implement a server side validation just like my bank does when I log in with the same computer. Wherein, the Spark API detects the Core coming online (or is already online) and sees a computer attempting to connect to this core and if the proper validation cookie is on the computer, the API grants permission. If not, the user has to request a new access_token. It can also be setup to detect I.P. addresses as well - if both computer & core are on the same IP - How secure is that. OMG ! We don’t need an access_token if this was implemented !!! as the Spark Team Server handles the security. Not the right IP accessing the Core (90% of the time it will be same IP for both Core & Computer and if not, at the new IP to the list via email verification. My bank does it.

Its not about Server to Server - 90% of the people should not have to even be involved at that level; is this not true ?

People use Browsers – Programmers use Server Side / Terminal Stuff.

If my products are going to use the Spark Core, its got to be KISS. Plug & Play. Easy to follow process.

I’m sorry if I am being too blunt about this.

I and 10 Million people worldwide could design a simple webpage and use the Core IDE to hide the access_token.

1,000 programmers of these 10 million would be able to effectively setup https or Telent or PHP Proxy or Putty.

I’m speaking for the 999,000 who will more likely stay with Arduino, BeagleBone & Raspberry Pi.

Okay, rant over. Back to my Rabbit Hole :rabbit: in my underground lab :feelsgood:

Its not rocket science unles engineers make it complicated

DISCLAIMER: I think this may get a little rambling-wordy. It took me 45+ minutes to compose this reply, so bear with me. Also, I'm no end-all-be-all expert on this, but I do have significant experience with it -- I wrote the core framework and 80%+ of the code for a web application that has access to hundreds of millions of records of private data. We haven't been hacked, but that's not to say that it couldn't happen (no mortal is infallible).

TL;DR: Security isn't easy, but it could possibly be made a tiny bit easier.

I like the core+client IP address verification, but I don't know how effective it would be. I know I'm not a typical web user by any means, but I access my Cores from home maybe 10-20% of the time. The rest of the time is when I'm out and about at work, out with friends, demoing at Maker Faire, etc.

The other method you compare to how your banks work is similar to how it works now, except the bank has already written that custom web app for you. They still communicate with some other behind-the-scenes API using some form of security handshake similar to oAuth (if not using oAuth itself directly). They then issue you a temporary session key that your browser transmits with every single request. HTTP is a stateless protocol, which means that every single web request you make to your bank doesn't know anything about the other web requests you've made. So, to remind the server that you are who you say you are (and it hopes you are), your browser sends some sort of token/key/identifier with every request. You're not sending your access token directly, but you're sending something that eventually pairs up with your access token. All of these access tokens and keys and IDs and whatever else are usually created with a very short time-to-live meaning they expire within hours or minutes.

Security isn't easy. If you want your data to be super secure, you're going to have to make your life much more miserable. An analogy would be you and your home. You may feel a relative sense of security within your own walls, but, if someone really wants in, you aren't. It's easy to pick locks, break in doors, throw bricks through windows, etc. So, you are actually sacrificing security for the convenience of having doors and windows. You could have steel doors and 1-ft thick windows, but instead of paying for it by sacrificing convenience, you're sacrificing your wallet. There's just no easy way around it. You will always be sacrificing convenience for security.

However, there are some ways that it could be made a little easier. For one, short-duration access tokens could be issued. I'm not sure if this is possible at the moment by looking at the docs. That way, you could expose your access token, but it's lifetime is limited. You could manually delete access tokens from your code, but it is an extra onus on you to do the work. Then again, though, if even a temporary access token is exposed, you are exposed for that duration as well. Perhaps you could flag the temporary access token as being IP-based for an extra layer of security, but if you are using a mobile phone or computer and hop wifi networks or cell towers, your IP address will change and invalidate that token temporarily saved in your browser. Even then, though, whatever temporary token you negotiate is only as secure as your web app. Your web app would have to do some sort of authentication to verify that the user is someone you wish to grant access to that temporary token.

Another idea would be to implement access control lists (ACLs) with given access tokens. That way, you can generate a read-only token that can only read your Spark.variable()s, but not write to your Spark.function()s. It's possible that you could extend it down to the variable or function level so that an access token can only read a single or given set of variables or write to a single or given set of functions.

Another option that sort of exists now is authenticating with your build IDE credentials. You can build a web page with a login form that directly authenticates with the Cloud API and returns an access token. You don't have to hard-code usernames, passwords, or tokens anywhere in the page. You don't even need a token-hiding proxy. When you send the form posted credentials, it has to go over HTTPS, so it's as secure as your browser running on your computer. However, it's still on you as the the web page builder to remember that token in a cookie, URL hash, URL query string, HTML5 local storage, etc. so that you can send it with each API request. There's actually a working example of this in my spark-control-panel mobile web app. Anyone can clone that repository and use it immediately without having to hard-code any tokens or credentials. As soon as the app loads, it checks the HTML5 local storage to see if there are any saved credentials. If not, a settings page is loaded to enter your username and password that authenticates against the web IDE login.

Perhaps that last method is what you're leaning towards? Maybe a browser-ready JavaScript library not all that dissimilar from the Spark CLI would make life a little easier.

I'd really like to get @Dave's and @jgoggins's opinions on all this. I'm about 90% confident that at least one of them has thought about this stuff already. I think it comes down to priorities -- there are still critical pieces that need to be finished or fixed before they can begin iterating over existing functionality to make it easier. What exists now works, but, like you said, it could definitely be made better and/or easier.

We can thank the engineers at the NSA and Mr. Snowden for all the security advancements over the recent months. Heartbleed didn't help, either. :wink:

... and I was going to try to go to bed before 2:00 AM tonight!!!

2 Likes

In terms of developing a web app, that would actually be more complicated than just sending the access_token. A cookie basically IS an access_token, that gets automatically sent by your browser (via the javascript running in the "web app"). That first time you login you are in fact validating who you are, and the device_id-access_token (aka cookie name-value pair) is stored on your computer for subsequent access to whatever it is you're accessing.

You can already do this with the Spark Core, if you wanted to. You just need to write a fancy pants web app that gives you a username and login field, and then with that you can retrieve a list of devices and your access_token, and save that info to a cookie. That can then be read the next time you open your app.

In terms of that being more or less secure than storing the access_token in an HTML file... it's not any more secure than a PHP proxy or non-public HTML file. Well it might be a little more secure if you also request new access_tokens from time to time (aka force a logout, re-login, etc..) ... but you can do the same thing in any web app, so long as you code it to do that.

I think you were originally more concerned about the difficulty level though... and this would be much harder to code... your average tinkerer is probably not going to mess with it. Cookies that is. It's much much easier to just format a POST request and send it via an Ajax call. You still have to do that with cookies as well, but now you have to create the web app that makes (bakes?) you your cookies. :cookie: :cookie:

All that said, you are NOT forced to change your access_token. I'm not sure what you are using that's making you change it, but it shouldn't do that. I'm still using the same access_token that I freely shared with everyone at the Pebble HQ... that I've been using for months and months. ruht roh... better check my GardenCore for foul play! hah... really though, I'm not worried.

Oh, this is news to me! :stuck_out_tongue:

How often does it expire?

Also, i was thinking, as a security concern, since spark core details (including ID) can be accessed via the URL : https://api.spark.io/v1/devices?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxx

...can't a script just run through random access tokens and when it hits a successful one, make note of the code ID/s?

cya
R

@wgbartley,

Thank you for your post. I know a lot more about the possible techniques that could be considered. I realy do appreciate it and I also would love to see @Dave and @jgoggins comment as well. All 40 or so members need to chime in ? What do you all think ?

I hope you can reset peacefully tonight knowing you are appreciated.

I started this Thread as a means of pointing out two issues:

  1. Docs do not discuss access_token secuirty risks if this key is placed in a webpage on the internet.

  2. Best Case security methods should be similar in both Cloud (https) and non-cloud enviroments (http).

10 Points for your post !

@Rehann,

I take odds to the access_token expiring as well. For best Security I place my access_token inside the core IDE Program. Then use a variable and keep the html I use behind a firewall on my local network. I will have to Reflash my Core everytime the access_token expires. :frowning: a real bummer.

What do you think about having similar security methods for accessing the core for both Cloud (Https) and Non-Cloud access (http) ?

Oh @Dave, tell them why Brute Force attacks won't work :wink: Or don't tell them why but just tell them...

1 Like

Technically, yes. Realistically, probably not. Depending on the length of your web IDE password, it'd probably be much easier to guess that with your e-mail address than attempt to figure out access tokens. I don't know if the Spark Team has it implemented, but this kind of brute force attack could be easily thwarted by enabling anti-hammering measures to identify and block these sorts of random token guessing (e.g. too many failed attempts from the same IP address would result in a block). I don't know the math off the top of my head, but it would likely take years to guess any significant access tokens. It'd be easier for an attacker to buy a round-trip plane ticket from their cave in Siberia and knock on your front door to ask for your access token. :wink:

1 Like

Ooh, I love a good security conversation!

There are lots of questions being posed here, so I’ll try to summarize and respond:

1.) What is the best / most secure way to control a core(s) / let users control their cores from my web app?

Storing your access_token in plain html or javascript on a public web page is not super secure unless you’re controlling access to that page, and your traffic to that page is encrypted with something like SSL.

The Cloud API supports a partial implementation of OAuth ( http://en.wikipedia.org/wiki/OAuth ), which we’re continuing to build out. OAuth provides a way for third party sites to let users request access to resources like your core, without giving away full control, or blindly trusting another site. This is widely used across the web, for example, think of any site that lets you “login via twitter/facebook/etc.”

I think the plan is to add controls so you can decide / disable access to third party sites and apps you’ve authorized. It’s the responsibility of those sites to securely control access to those special session tokens.

2.) What is the best / most secure way for my core to make a secure connection somewhere else directly?

The Core as an embedded environment, has limited resources. The secure connection it builds to the Cloud server is very resource intensive, but that is still less intensive / more optimized than your average HTTPS connection. We’ll be releasing the local cloud this summer which will let you have the same encrypted session with your core, and you can add any server-side code you like to make direct web requests on behalf of your core.

3.) Can I add a secondary layer of security on my core? Like a special password?

Totally! Fun idea! Although I’m not sure why this would be needed, you could definitely do something like create a spark function where the commands must always be preceded by a password. Something like:


setup() {
   Spark.function("whosthere", whosthere);
}

int whosthere(String command) {
  if (!command.indexOf("secretPassword!") != 0) {
    return -1;
  }
  //else secret stuff!
}

4.) On the business of cryptographic hashing schemes

As an amateur security nerd, I feel obligated to recommend you don’t use MD5 as a secure cryptographic hashing scheme. A cryptographic hashing scheme is only as good as it’s collision difficulty, and many of the older schemes are weakened or broken entirely. Many of the older schemes are also so easy to calculate now-a-days that rainbow tables exist to reverse engineer the saved values. http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms

5.) Brute forcing access_tokens

I don’t recommend testing our API ban hammer. The tokens are a big chunk of cryptographically secure random data that’s been cryptographically hashed and digested. If my math is right, each guess would be something like one in 1e48, and your requests will be slowed down and then cut off before making a dent in that space. That being said, I haven’t had someone try to test that yet, but again, please don’t do that. It would consume resources someone else could be building cool stuff with. If you want to brute force your access_tokens against your local cloud at home, then definitely go for it! :slight_smile:

Side note: We welcome advice or emails about security concerns you might find, and we sometimes reward responsible disclosure with free stuff! http://en.wikipedia.org/wiki/Responsible_disclosure – I love responsible disclosure, and welcome it!

Thanks,
David

6 Likes

Thanks @Dave for this great information. May I suggest your post “edited for docs theme” be added to docs.spark.io ? We do need something about access_token security in those docs and especially the part about it not being secure to place a access_token in a webpage on the internet.

I do have a question for you though.

If the core access_token was to be stored in the Core IDE code itself and using an external java file located on @kennethlimcp’s SD Card connected directly to the core. And the use of a variable set in an external java file located on this SD Card that verifies the acces_token sent with a command is the same as the access_token in the IDE Code on th Core to allow commands from any device or platform and even a webpage on the internet. Would this not also work for work for both Https: (cloud API) & Http (Non-Cloud) connections ? Would this be secure ?

Thanks, Bobby

"Back to the underground lab :slight_smile: "

Added to the backlog :wink:

2 Likes

@BDub,

Good Idea, Thanks ! And, I already added to the document needs thread.

One of my questions was about creating new sections. I can add to Github but, I now know where to post my addition requests for docs.

Thanks again for the help.

Bobby

1 Like

Hi @spydrop,

Cool, yeah I think adding some notes on security best practices would be a good addition for an app developers guide, definitely!

Hmm, it sounds like what you’re describing is essentially storing a secret on the core, and using that to verify communications with that device, is that right? It sounds like you’re talking about the first “A” Authentication ( http://en.wikipedia.org/wiki/AAA_protocol ). While Authentication is a good thing to have, that doesn’t necessarily protect the messages themselves in the absence of some kind of encryption. (If you’re doing direct local messaging without the help of a service).

I hope that helps!
Thanks,
David

1 Like

If you added a second layer of security on the Core by requiring an extra password to be sent to enable operations on the Core… the access_token alone can still allow anyone to reprogram the Core OTA, and essentially bypass the extra password. This is of course assuming you knew what to reprogram it with (let’s assume the Core’s application was open sourced on github). This is all just a brainstorm of ideas… I don’t mean to make any kind of a point here :wink:

2 Likes