CloudKit security for storing messages - ios

I'm considering using CloudKit to power my messaging app. With CloudKit, you can set permissions, for reading, writing and modification/deletion of data:
World - Any user, whether authenticated or not.
Authenticated - A user who is logged in with iCloud
Creator - A user who created a certain entry will have creator permissions over it
The permissions don't break down enough that I'd be able to specify 'Any user who has a relationship to a message', ie the sender and recipient.
Within my app, I'll only ever make the calls to retrieve data relevant to that particular user, so messages to which they're the sender or recipient. My concern is that with every message stored in this public database, I'm wondering whether a user jailbreaking the app, or doing something else malicious, might be able to insert calls to retrieve additional data, such as the data regarding other users.
If this is possible, is there another way that I could secure the data intended for between two users?

I'm testing a similar idea and what I found is you should use encryption with public/private key, then your sender must encrypt his message to the receiver with the receiver public key. Then only the receiver will be able to unencrypt the message.
I don't like the idea to give access to modified the record to others users, so you should give read access to the others users, buy only the sender will have total access, so, your app should delete old messages. If your receiver need to save his messages, is better to use his private database after read and unencrypt.
This is the general idea.

Related

iOS Firebase Database Security. Create New App User: Checking for Existence of Username

I have an iOS app where all user and data functionality is handled through firebase. For all required firebase functions, we have set the rights on firebase set such that they are secure (i.e., everyone can only read/write the parts of the database that are relevant to them).
Now, in the “create new user” screen of my app, obviously no user is signed in yet, but I would like to check for availability of the desired email address and username.
How can I conduct the check without making a list of all email addresses and usernames openly accessible in the database (i.e., setting the rights such that everyone can read them).
Keeping an openly accessible list of usernames in the database in my view is a security risk. On the other hand of course no user is signed in when on the “create user” screen, so I don’t know how to restrict the access.
Thanks.
There are many ways around this. Here are a couple suggestions:
Sign the user in anonymously before choosing a username. This would then give them the access you're looking for without making the data public. Then, when the user creates an account, the anonymous account can be converted, as shown in the documentation.
Use an HTTP-triggered Cloud Function, passing the username the user wants to try as a query. Inside the function, check the database for the existence of the username, and then respond to the HTTP call accordingly.
I'd probably do the former because it'll return a quicker response. Cloud Functions can take time to spin up if they haven't run for a while.

where to store user info after login to swift ios app

I'm creating simple user login at the beginning of my app. After user submits correct username and password, my script from server should return some parameters which I should store in some sort of local database, and check for these parameters every time when new view appear/loads.
My questions are:
1) which type of local "database" should I use, which one is secure so no one else from "outside" can access it, because if someone could than he could set my logins by himself (keychains, user defaults etc.)?
2) which parameters should I return from server, which one of them are essentially from security when checking if user is logged in - I'm thinking of username and the token - if user is successfully logged in, than server script should create some type of token which will be stored in online database. Every time user makes some request from app to the server than token is checked, if it exists in app and if it exists in server database and if they are equal.
3) How should I check if user is logged in when new view is loading in the app - should I just check if variables exists (for example in Keychains) or should I connect to the server and check every time server database?
for storing sensitive user data(password, api token, email) you should always use Keychain for this purpose.In other hand there is Realm also offer secure way to store your data.Its easy to use, you just need wrap data objects with realm base(Object) class and mark properties with dynamic attribute.For basic login system i think user name, email and api token good enough.But depends on api needs you can include here phone number, birthday etc.For checking user authorization I think validating api token good enough in most case.
There is also most secure techniques to improve data safety like keep database property names in keychain.Hashing sensitive data parts in api calls.Last thing you need use https for api communication.

Authenticate registering users against already existing User profiles on Server

I am busy with a Web Api 2 project in VS 2013. We have a number of established applications, and a couple hundred clients with in turn thousand's of users registered at each client.
I am assigned with creating a Mobile App (Cordova/Phonegap), but before I can do this I need to create an API that can handle http Requests from the app.
We have a large database with 173 tables including a user table. This database exists at each client (with their own users). I have imported the default AspNet... tables into our database, changed the connection string and have successfully managed to register users on our database.
My questions is this: Is it possible add additional registration requirements? e.g. in addition to Email, Password, (ConfirmPassword), I'd like to add:
1) Mobile Number
2) Identity number
so that they are also written to AspNetUsers, and then somehow create a foreign key link to my existing USERS table, let's say on ID number provided by the user?
The idea is to not let any user register with the mobile APP that is not already registered on the database.
So, how it should be able to work in my head is not necessarily correct, but here is a summary below:
1) User download app from app store.
2) App shows register/login screen, user register with Email, password, ConfirmPW, MobileNr, ID
3) App sends HTTPS Post request to API with above info.
4) API gets info, before binding to model and writing to db, first does a query to existing User table. If a user exists with ID and mobile Number, then AspNetUsers record is created (with FK reference to Users table). If not, user is not allowed to register, and message is returned, e.g. You need to be a Client of "CompanyName" to register.
5) After this, user logs in and uses Bearer token etc. (default log in way).
I know this is not necessarily how it will work in practice, but can something like this be done. I don't want to re-invent any wheel, only add what listed above. Thanks in advance.
Yes, you can customize the User information. You need to customize the IdentityUser class. Here is a great tutorial on how to do it. I even managed to change the normal Id in the AspNetUsers table (which is nvarchar by deault) to an int.

How to implement 'User' functionality in an app?

This is probably a repeat. However, the other answers haven't helped me out. So, here goes.
I'm working on an application and we with need to add 'users' to it. We'll be giving the option for people to sign in with Facebook, Twitter and LinkedIn. I've worked with these APIs before, however never combined them globally.
How can I maintain and manage these users that will use different services to log in. I'm confused as to how they would be stored in a database, would I need to have a different table for each different social service or is there a way to implement a table that will house all users in one place.
From what I understand, you're asking how to manage, store, verify users that will be logging in your application through different social services.
This is how we've implemented it through the various projects we've worked with. From the list of services you've provided we've worked only with twitter and facebook, so I can only speak about that.
Setup:
We have a web service that our iOS app communicates with such as when the iOS app needs to make a request call for user login the server would take the user details trying to login and gives back a response where the app would then do whats necessary.
We have a database stored on the server with a users table which is used to verify a user.
That being said, you need to understand whats common between most social services, or to at least know what the property is that is used by these social services to uniquely identify its users. In this case they all use email to identify users.
You'll find that when interfacing your app with these different APIs, they like to use a login session key used for unique logged in sessions.
So on your database you would store whatever details you want to save of the user, but know that you need to store atleast the username, password (encrypted), email (for identification, unique column), and login_session_key.
Just double check that linkedIn does have something like a session key that it creates when a user logs in with that method. Facebook and twitter do. Send at least the 4 main data properties needed (username, password, email, session) to the server You then follow this sort of approach:
New user
If the user that is new tries to login, the server first checks the email provided even exists in the database, if it does not then you sent a response back alerting the user that the user does not exist; your app would then take them to the register screen for example.
If the user is in the registry page, save all the details you want to store of theirs including username, password and email.
Members
If the user logs in the email will exist on the server side, its an existing user so just update the session key that was sent from the app on log in if the password matches, (in some apps these session keys are used through the life cycle of the application being used, with each request sending the same session key and if at any point the session key does not match during app interaction, it can be concluded that the user has logged elsewhere on another device perhaps.
if the password does not matches return the appropriate message.
That's about it really. We're able to store all facebook and twitter users in one table.

How to store non-standard web authentication?

In the web API my app communicates with, the authentication process is designed in the following way:
The user enters the name of the group that he/she belongs to.
The server sends the list of group members.
The user chooses a user name and types a password.
My app sends a hash constructed of the group id, user id and password to the server to validate the credentials and in case of successful validation uses this hash in further transactions.
Having this process, I do not get standard NSURLConnection messages like connection:canAuthenticateAgainstProtectionSpace: or connection:didReceiveAuthenticationChallenge:.
I can deal with it per se, but when it comes to securely storing the credentials, I get confused. Is there a way to do this via some built-in iOS SDK methods or I have to write the hash in a file manually, for example? What's the proper way?
The keychain seems the best option to store the user's credentials/hash.
Check out http://developer.apple.com/library/mac/#documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
And https://github.com/ldandersen/scifihifi-iphone/tree/05e64ff2814a8192c43f1f81eb8e09dc3764fa18/security
Be aware that while the keychain is probably the safest place in iOS to store this kind of data, it isn't entirely secure. But considering the data you want to store, it's probably well enough.
Edit: Look at http://overhrd.com/?p=208
You'd be able to access the data on your keychain with simple calls of this nature:
[Keychain setString:#"hashhashhash" forKey:#"userHash"];
// later on…
[Keychain getStringForKey:#"userHash"];

Resources