Best way to store OAuth token iOS? - ios

I am writing an iOS app that uses Twitch.tv's API to allow my app to access their users content. They use the OAuth 2.0 protocol for authentication. I need to use this access token every time I make a request to access a users info.
My question is where should I store it?
Should I make a class that has it as a property? In that class I could also store my Redirect URI and Client_ID to keep things in one place.
I thought about NSUserDefaults, but I read it's not very secure.
What is the best design pattern for this approach on iOS?
Thanks.

The way your question is worded you seem to be confusing the use of the word store to mean two entirely different things. If you use NSUSerDefaults then the token would be stored to file and would persist if the app is killed. If you make it a property of a class it is being temporarily stored in memory and would not persist if the app is killed. Your question is therefore asking should I use Apples or Oranges.
If you need persistent storage for sensitive data then you should not use NSUserDefaults, instead use the iOS keychain.Use of the keychain is a bit too lengthy to describe here.
The keychain is encrypted but only using the user's 4 digit pin code, which could potentially be brute forced cracked. So you could also potentially encrypt it.

Related

Best practice to safely persist user data to minify API calls

I have a react app with a rails backend. Users must be logged in to use certain functionality or must be premium users to access premium functionality.
My app makes an API call to the backend on every page load to check if the user is logged in and if so sets the state of the react app to include the user object the API sends as response and sets loggedInStatus: "LOGGED_IN".
The app uses the state and user object to accordingly allow or prohibit functionality.
This means though that on every page load an API call must be made which seems inefficient to me.
An alternative could be to store the data in localStorage and only make API calls and update the user object in localStorage if changes were made to the user. However, storing information like email addresses in localStorage doesn't seem very safe to me.
Is there a way / best practice to securely store and retrieve senstive information without the need for API calls on every page load? Please excuse if this questions seems rather broad, I don't know how to phrase it better.

Rails - Store data that we can't read but that our app can?

My friends and I are building a Rails app, and we were wondering: Is there any way our database can store user information in a way that we can't read (i.e. we want to honestly say to users, "we can't see your phone number!"), but that our app can still freely read and interact with? We basically need to be blind to the data but still capable of having our app read it.
The only way I can suggest to do this is to encrypt the data on the client side using a password that only the client knows. You will need to find a client-side Javascript encryption library that will encrypt the user's phone number in the browser before sending it to you. Your server will not be able to do anything with the encrypted phone number except to redisplay to the user or to anyone who has the password.
Stanford has a javascript encryption library you may want to explore.
If you want your server to be able to do anything useful with the data (other than storing it), then there is no truly secure way to guarantee that you cannot see the data. Someone in your company, whether it is dev ops, DBA, IT, etc will be able to access the data if they want to. The user will just have to trust that you are keeping their data private.
You can set up encryption and permissions to restrict who has access to the data, but in the end, at least one person other than the client will have access.
It's related to user permissions. You should check the user permissions which are saved on DB and which user retrieves data

Rails way to store data on client for long periods

What is the preferred way to store some data on the users computer for long periods of time. I am unsure how long a session lives. As an alternative I could store the data in a cookie, but here I can't find any high level storing API which also takes care of signing my data and make sure it is not tampered with.
How do you typically solve this problem of having a persistent user id between sessions.
Check out these links, they might help you on understanding the cookie handling:
http://m.onkey.org/signed-and-permanent-cookies-in-rails-3
http://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-rails
http://www.tutorialspoint.com/ruby-on-rails/rails-session-cookies.htm
You handle a persistent user with a cookie--but you are quite limited in how much data you can store in a cookie (4K?).
Large sessions should be stored on the database. Some browsers support local storage (HTML5) which may also be an option.
If you want to guarantee it can't be tampered with outside of your application, you should store it on the server-side in a DB. The signed cookies make tampering difficult (or at least detectable), but you're still size-contrained.

mvc site, most secure way to preserve login credentials

ok so, i have this dilemma on how i should save login credentials in mvc at the same time avoid as much hit on the database. i know i can easily use Forms Authentication to save a User instance but is it advisable?
At the moment the way I do it is I store the User Id in a cookie which i then would access everytime an Action gets called that would "require" a login access. Before the action gets accessed the User Id will be used to retrieve a "New" User instance. This will be the same on every Action, I don't store the User in the cookie as I feel like once the cookie is compromised everything about the User shall be available for the hacker (Userid, email, roles, etc)
So if i have a ton of actions that would require a login that will be difficult on my bandwidth. What do you think of the method I'm using? Should I change it to have all the User object be stored in the cookie with a short timeout? Any ideas are greatly appreciated.
thanks!!
It seems like you are trying to address a bandwidth issue. That alone would suggest that you shouldn't store more than you have to (ie: session id) in the cookie.
There are two major problems (among others) for using cookies.
1) They are sent up on every request
2) There is only limited amount of information you can store.
In general, trusting anything the user gives you (that includes encrypted cookies) is bad.
How many concurrent users do you foresee having on your website? Keep in mind that the database will be able to cache certain calls. Furthermore, if you are using a ORM like nhibernate, you will get 2nd level caching there. If all else fails, could you use the in-memory session management?
The biggest problem I have with putting userid's in the cookie is the entropy of that key. Say your userId is an email. All I have to do as an attacker is guess a userid that is valid in your system, and I will "automatically" become that user. The reason why people use sessionID's and then retrieve the user is that in theory sessionID's are harder to guess.
My suggestion would be to use database session management if you are in a load balanced situation. If not, use in-memory. It is fast. Memory is cheap. And unless you are storing 10's of mb of data in session for each user, and you have 10000's of users, you should be fine.
As Ken stated, you should probably be using the standard [authorize] tags available with MVC as opposed to creating your own method.
It sounds like you pretty much implemented form based authentication and something comparable to the [Authorize] attribute.
So if i have a ton of actions that would require a login that will be difficult on my bandwidth
Forms Authentication uses a cookie and is baked into the system. If you don't want to store your user information in SQLServer there are plenty of other options.
It sounds like you are trying to implement something that is already done. In my opinion, let's leave the security stuff to people that know about security. I would suggest working within the framework provided unless you have proof that you solution needs something else!
There is a UserData property on the FormsAuthenticationTicket object that could be used to store additional data other than the Username.
I had a project that had a similar need. I stored the values as a NameValueCollection encoded like a query string:
"email=myemail#some.com&roles=Somebody&roles=Special"
(there's also a handy HttpUtility.ParseQueryString() method that is useful for getting the values back out of the UserData property)
You can use the FormsAuthentication.Encrypt and FormsAuthentication.Decrypt to convert the ticket to and from the Cookie value.

Building RESTful API with MVC for an iPhone app - How to secure it?

I'm going to be writing the services for an iPhone app being built by a third party vendor.
I'll be using ASP.NET MVC to accept posts and also return JSON formatted data.
My question is, how do you secure it?
Just using an API key perhaps? Would that be enough to ensure that only data from the iPhone apps are allowed to hit the specified services?
I'm sort of struggling with the same concepts myself. I think the first thing is to do HTTPS only, so that it's starting out more secure than not.
Next, it depends on how you're going to do authentication. If all you need is an API key, (to track which entity is accessing the data) that should be fine. If you also want to track user information, you'll need some way to associate that specific API keys can access specific types of records, based on a join somewhere.
I'm looking at doing forms auth on my app, and using an auth cookie. Fortunately ASP.NET on IIS can do a lot of that heavy lifting for you.
Example time: (I'm sure I'll need to add more to this, but while I'm at work it gives something to gnaw on)
Forms auth:
Send a pair (or more) of fields in a form body. This is POST through and through. There's no amount of non-reversible hashing that can make this secure. To secure it you must either always be behind a firewall from all intruding eyes (yeah right) or you must be over HTTPS. Simple enough.
Basic auth:
Send a base64 encoded string of "username:password" over the wire as part of the header. Note that base64 is to secure as a screen door is to a submarine. You do not want it to be unsecured. HTTPS is required.
API key:
This says that an app is supposedly XYZ. This should be private. This has nothing to do with users. Preferably is that at the time that the API key is requested, a public key is shared with the API grantor, allowing the API key to be encoded on transit, thus ensuring that it stays private but still proves the source as who they are. This can get complicated, but because there is an application process and because it won't change from the vendor, this can be done over HTTP. This does not mean per-user, this means per-developing-company-that-uses-your-api.
So what you want to have happen is that for the app accessing your data, that you want to make sure it's an authorized app, you can do negotiation using private keys for signing at runtime. This ensures that you're talking to the app you want to talk to. But remember, this does not mean that the user is who they say they are.
HOWEVER.
What you can do is you can use the API key and the associated public/private keys to encode the username and password information for sending them over the wire using HTTP. This is very similar to how HTTPS works but you're only encrypting the sensitive part of the message.
But to let a user track their information, you're going to have to assign a token based on login based on a user. So let them login, send the data over the wire using the appropriate system, then return some unique identifier that represents the user back to the app. Let the app then send that information every time that you are doing user specific tasks. (generally all the time).
The way you send it over the wire is you tell the client to set a cookie, and all the httpClient implementations I've ever seen know that when they make a request to the server, they send back all cookies the server has ever set that are still valid. It just happens for you. So you set a cookie on your response on the server that contains whatever information you need to communicate with the client by.
HTH, ask me more questions so we can refine this further.
One option would be to use forms authentication and use the authentication cookie. Also, make sure all the service calls are being sent over SSL.

Resources