How to ensure/determine that a post is coming from an specific application running on an iPhone/iTouch? - iphone

Building an iPhone OS application that will allow users to anonymously post information to a web application (in my particular case it will be a Rails based site) ... and I want to ensure that I only accept posts that originate from a specific application running on an iPhone/iTouch.
How is this best accomplished?
(btw, if your answer applies to Android please feel free to post it here as well as I'm curious to know if the techniques are the same or vary).
Thanks

The best way would be to implement a known call and response pattern. Send a value of some sort (integer, string, hash of a timestamp) to the iPhone/iTouch application. Have the application modify this information in a known way and send it back for verification. Then all you have to do is use a different modification algorithm per-platform and that will verify what type of device is being used.
VERY simple example:
Server sends 100 with the response to an iPhone.
iPhone adds 10 to this value and sends back with request.
Server detects the value was increased by 10 and now knows it was from an iPhone.
Then on your Android clients add 20 and on another platform add 30 and so on...

You could also add a hidden field in the form. or in the data being passed up if it is XML or other format

Encrypt or sign something using the public key of a key pair, then decrypt or verify it on the server with the private key. Ultimately, anything that can be sent can be duplicated, be it a spoofed html header or an encrypted block. The app has to know the secret handshake, and anyone with access to it (and sufficient technical skills) can figure out the secret handshake.

I would suggest the following approach.
Build an ssl enabled access to your rails app.
Now create a user account for every plattform you want to use and enable your applications to log in with the correct key. If you use the ssl standard in a correct way there shouldn't be a way to sniff the password and you can use standard components on the rail and the phone side of your app.
You then need to secure the login credentials on your phone with the appropriate technics. Eg. put it in the keychain on the Iphone.

Related

Authenticating calls from Phonegap app to REST server

I'm building an app with Phonegap. It simply reads xml feeds to display latest articles uploaded by a school for parents to read.
There will be an option where each user of the app can decide whether they want to receive Push Notifications or not. I have a simple database table where the device's registration i.d. from Google Cloud Console is stored. When the user clicks "yes", the registration i.d. is generated and stored on the server. If they then click "no", it's deleted. I want to secure these call to the server with basic HTTP authentification.
Any documentation I have seen on basic authentification describes the sending of username and passwords. But with my application, there is no username or password as the users do not need to sign up. What do I send to authenticate the client? Would there be a key hard-coded on the client side and sent with each request? Couln't this be easily exposed by unpacking the .apk?
I object to the premise of the question. I actually see this as less a security issue and more a preferences issue. Understanding the distinction makes the development of your feature much easier.
Simply modify your application to allow the user to configure what he or she wants to see in the settings and then store the preferences wherever you want on the client (like local storage). The server can then push as before, but the app should simply refuse to render those pushes that the user doesn't want to see.
If you want to simply disseminate non-sensitive content to the users who want to see it, this is a preferences issue and/or a publish/subscribe issue. But it is not a security issue.
Since you have access to server side, you have the control of the whole process. So, in order to handle that, you may think about something like session cookies that a web server creates in case of normal authentication.
I have done something similar and what I've done is to generate a kind of token server side that is stored in the cookies of the device or the localStorage.
So the process flow should be something like this :
Generate a token and store it on the device (cookies or local storage).
For each request, send this value in a http header
From server side, you may identify the user from that token.
For example : you maintain a table that identifies device/token.
That's it
In addition to what the other answers said you can pass a custom useragent string as part of the requests, and validate it matches what you expect. It's not a sure way to 'secure' requests, but along with a (simple) token system and HTTPS this could be enough for your needs.

How to secure JSON requests from iPhone?

I have a web app with a JSONP API I'm using with my iPhone app. How do I secure this so requests from other places won't be able to access my API?
Clarification: My data isn't that important. You don't even have to sign in to view it. I just don't want by my DB to work on queries from other sources.
You have embarked on a very very complicated subject. Prepare yourself for some very long nights of reading various cat and mouse techniques of securing your app. I think your best bet is to put a secret string in the header of each request. Something like this:
Secret-Header: #$F#FQAFDSFE#$%#ADSF())*
Validate that header on the server side and use SSL. Someone could easily respond to this post with "Well that doesn't stop this, this and this" and they will be right. The question is, are you a bank that is worried about someone draining your client's accounts? Or are you just worried about 99.9999% of the population not being willed enough to hijack your junk?
Some people have all kinds of opinions on this, but if your users require authentication to access the web services, just require the username and password to be sent in the header via SSL. They can still hijack your services, but wouldn't be able to see anything that they weren't supposed to anyway. That only works on a user level type of setup though. If it's completely public, you have to consider how unimportant your data is. It may not be as important as you think.
You can embed a private RSA key in the iPhone client and send a signed timestamp with each request.
The server would verify the timestamp against the public key and reject unsigned requests.
The enemy can disassemble the iPhone client and steal the key, and you can't do a thing about it.
(other than a blacklisting arms race)
You can use TLS protocol with client certificate.
http://en.wikipedia.org/wiki/Transport_Layer_Security
The only problem with this solution (not solved today) is that the client certificate is stored in the app binary and can be retro-eenginered.
One traditional way to do this is to take all of the url variables you are requesting, add a 'secret' string, and hash the whole thing and add it as an additional url variable. On your API side, you do the same thing, and if the hash matches what you were given, it's probably coming from your app.

iOS -> .NET WebService authentication question

I'm building an iOS app which will communicate with a set of .NET WebServices. I'm trying to find a way to ensure on the WS side that the calls being sent actually came from the iOS app.
There is, of course, a "login" method which requires a username/password combination. I would like to add a "security token" to this method, which I can use to validate that the request is coming from the iOS app.
Since this is a parameter to the login method, is must be something known by the app and the web service BEFORE a valid login occurs. Additionally, it should be something which is impossible (difficult?) for another application to fake.
Are their any best practices / standard methods for this sort of exchange? Am I even thinking about the problem in the correct way?
Thanks in advance!
Take a look at the oAuth specification (used by Twitter) it requires that a user is verified first, during the process a series of tokens are exchanged, and then the token is used to sign the data during subsequent data exchanges.
It works on the principals of public/private matched keys, so you have one key that is always kept a secret.

How to architect a simple authorization scheme between IPhone and server?

I'm developing an iPhone app that lets users upload photos to a Google App Engine backend written in Python.
Data is transferred between the device and server via HTTP POST and GET. What is the simplest, most secure way to ensure only iPhones with my app can get data? Also, I don't want the user to enter in credentials, it should be invisible to her.
I could embed a key in the device and send that with every request which the server would check against. But a malicious user could potentially decompile the app and obtain the key. Any suggestions?
With your requirement that the user not enter any form of password, your options are severely limited. As you note, any shared secret key in the app can be pulled out by someone via binary extraction etc. -- in effect, you can't stop a really dedicated cracker finding out the secret and then just submitting that to the server.
There are approaches that are not watertight, but which might make it harder for wholesale abuse of your service. One example might be to release updates for your app every month (or two weeks, or whatever) that contain a new shared secret. Then obviously your web service has to expect the new shared secret, as well as accepting the exising secret, for each time period.
If your data is very sensitive, you might want to stop eavesdropping by using HTTPS; but as Nick says, if you use HTTPS for anything except authentication, you have extra hoops to jump through at App submission time.
Whenever you have a key stored on a device or in software that is accessible by someone it is subject to attack. iOS's keychain is generally a helpful way to store things you want to secure. However, it is still subject to attack. As with all security you need come up with a model that is appropriate for your application.
Also note that there are encryption export restrictions that you should familiarize yourself with if you be intending to use encryption for more than authorization.

What is the best way to secure a RESTful API to be accessed on an iPhone

I am looking for some suggestions on how to secure access to a RESTful API which initially be used by an iPhone application, but will have other clients in the future. The data exposed by this API must be kept secure as it may contain health information. All access will be done over HTTPS.
I was thinking that I'd like to require pre-registration of the iphones at setup and then also some type of PIN/Password on each request. So, simply knowing the password without pre-registering the phone/client won't provide access. I was thinking about somehow tying it to the iPhone identifier if that is possible, but not sure it would provide any additional security. The iPhone identifier is just another piece of information and it may not even be that secret.
So, some requirements would be:
Use some type of pin-based solution on the iPhone, but want more security then a simple 4-6 digit pin can provide.
No passwords could be sent in the clear.
Not be subject to reply attacks
Having to pre-exchange some data between client and server when setting up client is OK.
I would think that, if the application contains medical records, you would want to have the user authenticate every time they use the application or, at least, have some way of pushing down a disable message that renders the app useless in the case where it is lost or stolen. The 4-6 character password (pin) would also concern me with respect to HIPAA, if it applies.
You might want to treat it as a standard web app from the server perspective and do session-based authentication and access with a session that times out, perhaps after a long period, and re-authentication on timeout.
You could use SSL with client authentication. If a device gets lost, you can remove the certificate on the server. There are some obstacles though:
It is not entirely clear if/how you can do client authenticated SSL on the iPhone Unfortunately, there is not much documentation about it. Have a look at Certificate, Key, and Trust Services Reference
You have to create a private key for every device
You also have to figure out a secure way to transfer the private key to the device