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.
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.
… and I was going to try to go to bed before 2:00 AM tonight!!!