How to securely store AWS service ids for iOS? - ios

I'm developing an iOS app that uses Cognito User Pools / Federated Identities, Mobile Analytics, and S3 to manage various features of the app, and recently I have become concerned for the security of these features. I already use IAM roles to control the services unauthenticated vs authenticated users have access to, but most of these services use strings (e.g. user pool app client id or user pool app client secret for User Pools, or app id for Mobile Analytics) to give the app access to that service.
What are the best practices to securely store these strings on the device to be used when necessary? Is it even necessary to secure these strings since the app is using IAM roles?
If it is necessary to securely store the strings, I have read that using the CommonCrypto library to encrypt strings before putting them in the keychain is best, but I'm not sure what key to use for encryption since my user needs unauthenticated access to those services. Any advice would be tremendously helpful.

This is a common problem to any mobile app. If someone really wants to, it's not difficult to decompile the app and scrape the keys from it. It's great that you are using IAM roles to restrict feature usage. This will limit the blast radius of attackers, but not necessarily prevent them.
Wth user pools you also get a globally unique identifier which can be used with IAM to restrict what S3 you can use key pre-fixes (which act similar to folders) to limit the objects that users can access to pre-fixes with their unique identifier. You can refer to https://mobile.awsblog.com/post/Tx1OSMBRHZVM9V0/Understanding-Amazon-Cognito-Authentication-Part-3-Roles-and-Policies (Using user pools as the provider, which will use the identity id as the prefix). Depending on how you structure your app you could use this so each user can only modify their own objects. I don't think Analytics has any way of restricting like this... because it wouldn't really make sense for it.
As far as securing your ID's there are things you can do to help mitigate, but there is no fool proof way to prevent someone taking it. You could for instance have the app make a call to your server for the ID... but then an attacker could just call the server. You could encrypt it, which might make it more difficult for an attacker to get, but you have to keep the key somewhere and if the app could get it so could someone who decompiles the app. Unless your app users get some sort of password from outside the app and put it in there isn't a complete way to lock it against attackers.
Hope this helps.

Related

"Copy this file to your authentication server" - Firebase Custom auth

My goal is to prevent users of multiple login in. I do not want this to be client-side, with like the onDisconnect and onConnect values, but with a server check. I came across this answer:
How to prevent simultaneous logins of the same user with Firebase?
Which tells me to create a custom auth system. When I am following the docs (https://firebase.google.com/docs/auth/ios/custom-auth) I need to "Copy this file to your authentication server" (3c). How would I do this? I am just using Firebase and my little iOS app. I would like to manage everything on these 2 things, no server in between, is this possible? Or can this file only be uploaded through another server?
If above things are not possible, how can I server check if the user really signed in? I am using Cloud Functions, but I did not came across a trigger for a user signing in. Please no answers with onDisconnect/onConnect, I want it server side. A user may NOT login if he is already logged in. Thanks :)
Implementing custom authentication requires that you have a secure place to mint the custom token that identifies each of your users. You cannot do this securely with only client-side code, because that would mean everyone could claim to be whoever they want.
While you can use Cloud Functions for Firebase to implement a secure back-end without spinning up your own server, I highly recommend against doing that just for the purpose of preventing a user to sign in from multiple locations.
It's important when talking about security to split these two steps:
Authentication - a user proving to be who they are
Authorization - the authenticated user being able to use your app
There very seldom is a reason to keep a user from proving who they are. Your concern seems to fall onto keeping them from using the app from multiple locations. To do that, it's probably easier to track for each user where they are using the app from already using Firebase Database's presence system.
Also see:
How to handle multiple connections of the same user on Firebase?
Android - How to detect same user from multiple devices?
How to prevent same user logging in from different devices ? My app is paid , so I dont want credentials to be shared

Using DynamoDB without Cognito API

I am using DynamoDB or any AWS stuff for the first time and thus have a very little idea how they work. I have seen the documentation where it's mentioned that to use DynamoDB, using IAM and Cognito sync is better way.
I have a very simple requirement. I have an iOS app in which a user can register and login. The functionality is provided by a third party SDK, but I want to store the user information in the DynamoDB table named as Users.
I am not sure if I need Cognito Sync or IAM for this.
So My question is, is it possible to use DynamoDb in iOS without using these two extra features? If yes, then is it possible to do it with the AWS mobile SDK or do I need some other ways such as using RESTful APIs for that?
When you use Amazon Cognito, the service takes care of all the steps necessary to create a unique identifier for your app’s users and retrieve temporary, limited privilege AWS credentials. This means that you can follow security best practices, and use these temporary, limited privilege credentials instead of having to hardcode credentials into your app.
You can still use AccessKey and SecretKey with AWSStaticCredentialsProvider in the AWS Mobile SDK for iOS, but we discourage its use in production apps for security concerns.

In objective-c is it possible to set up OS-level account validation like Twitter, Facebook and Vimeo?

I'm working on an iPhone app that is logging into a webservice and it's been asked of me to get the account login management into the settings page (i.e. next to Twitter, Facebook and Vimeo). From what I've been reading about the accounts framework, it appears that only those few companies have that ability.
I currently have it set up and working asking for login info periodically and polling the webservice for validation, but we're trying to move toward supporting moderately offline use, which means we need to have some sort of account info managed on the phone itself.
Can I use the built-in account framework for our own login credentials or is that not something that's available to a regular dev and I'll have to look for another way to do it on my own? Is that something that the keychain would be better for?
Using the keychain to securely store the users credentials is a good idea to start.
If I am understanding your question about a "built-in account framework", I don't believe there is a local framework for account management on the device itself that I am aware of that would be useful in this circumstance.
I've had to build an app that needed to authenticate to a web service that also needed to have some offline access. I ended up recording the validated authentication date and time in the NSUserDefaults and would let the user use the app for a 48 hours period before they had to re-authenticate. Their data was queued locally and when they had online access again, I would re-authenticate and then sync the data. Not the most elegant solution but it fit the project.
I used AFNetworking (http://afnetworking.com) to track the changes in network access and used to blocks to respond to the changes.

Using google/twitter/linkedIn authentication in iOS/Node application

I'm trying to work out the best architecture for a couple of apps I'm developing.
In both apps I want to utilise google/twitter/LinkedIn/etc to provide authentication of a users identity. The app is composed of an iOS app which has an option to send data to a server which I'm writing in node.js.
I want to utilise either OAuth or OpenId to handle identifying a user against the above servers so that I don't have to put in an authentication system of my own. In other words, allowing users to re-use their ids when choosing to upload data.
I should also note that apart from identifying a user, obtaining a name and email address, I have not intention of using any of their APIs at this time.
I think I have two options:
Place the Authorisation code in the iOS client and transmit some sort of key to the server with the data which it can then verify.
Keep the iOS client fairly dumb, and handle authorisation from the node server.
I'd probably prefer the second option because it means I could centralise authentication and be able to support a web site as well. That's my current theory.
Can anyone who has done something like this give me some pointers as to the pros and cons, OAuth or OpenId, or links to some examples?
In our previous app we opted for a combination of the two approaches. We wanted to centralize our user data on our server in the event we needed to make future API calls on those services. We also wanted the native oAuth experience for the user on the client. Ie: on Android and iOS, the developer can have single sign-on / authorization run through the native Facebook app (if available), vs. popping-up a webview that serves the 'Approve' dialog. It's a better user experience in my opinion. Also for Twitter, the oAuth process may require a PIN code to be entered in the callback which should probably be handled on the client side.
You can pass the access token retrieved by the client to the server for storage and later use if you intend on making additional API calls on these services, provided you expect the token to be long-lived (ie: offline-access permission on FB).
In any case this is mostly a user experience decision.

Securing JSON posts from PhoneGap

I am trying to develop my first PhoneGap application, using MVC.NET to serve the JSON to the application. I am though in doubt how I can secure the controllers on my MVC.NET application so only PhoneGap applications can post to my server.
I e.g. have a settings controller where the user can update his/her settings, but how would I make sure that no one tampers with it?
I had plans to use the deviceID as the userid, so the user doesn't have to create an account to login, but does this rule out the possibility to make it secure, since I don't Authenticate the user?
You need to use the same sort of authentication/authorization/security mechanisms that you would for any other web site. This means that authorization information shouldn't be passed in the clear (use SSL, encrypted cookies). You should choose authentication information that is difficult to guess or impersonate (user id/reasonable password; I'm guessing device id might be less secure if it's broadcast regularly). You could store this information on the phone, but with varying levels of security, i.e., if someone gets physical access to the phone it's likely that they would be able to access the credentials you store.
You might want to look at the security wiki for more detail/information: http://wiki.phonegap.com/w/page/43660891/Security

Resources