How can I prevent anything other than my iPhone app from communicating with my Rails webapp? - iphone

I'm diving into web development and I've built a few basic rails apps, but now I'd like to begin learning how to securely connect my iOS apps with my Rails apps. For example, if I want my iOS app to query my Rails webapp for some data from the DB by passing parameters in the url...
http://mywebapp/mycontroller/search?q=keyword
...what are some common web development methods I can use to prevent anything (or anyone) other than my iOS app from successfully executing that search query?
I'm sure this type of forgery that I'm trying to prevent has a formal name, but I'm very new to web development and I'm still learning all the jargon. Thanks so much for your wisdom!

Use the trick that Rails uses in the protect_from_forgery by generating a unique key for you iphone app. Then ensure that your app passes that key in the requests to the server. You can then write a before_filter to ensure that the request possesses the key. If it does then you process the request. If it does not then you return an error with a custom message explaining why they can't have access.

You could create a hash and use it as a token which would be passed with each call to identify your application (hard coded value in the app) and the session (current ip address of the client.) So: hard_coded_value + ip_addressed -> MD5/SHA1 (whichever) = token. Your server would also have a copy of the hard coded value as well as the calling client's ip address, perform the same hashing function and compare the results. If they match, it's your app. If not, then it isn't.

you should add HTTP basic authentication in your web app (search file)
Refer these links -
http://en.wikipedia.org/wiki/Basic_access_authentication
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
Basic HTTP Authentication on iPhone
NSURLConnection and Basic HTTP Authentication in iOS

Related

Security on iphone / ipad application when calling a wcf service

I'm new with objective c programming and implementation of wcf, so i may or may not sound like an idiot with my questions. Was wondering what's the best practice in terms of calling web services from objective c.
My plan, for login, is to create a wcf service to check if the username and password exist. If it returns TRUE then you create a "Cookie" that will store the session on your app? I'm planning to return the Id of the user as well so that whenever the user requests for some data change from the iphone app it can know which user it is. BUT I'm skeptical about returning the users Id. Is it safe? Or should I generate a type of GUID or token to return from the WCF to my iphone, store that and then whenever they request for a transaction then WCF can verify the user?
Can somebody please point me to the right direction as to where to start in terms of objective c security.
Thanks!!!
I think you are on right track :-)
If your server supports session id mechanism then in response of login send a unique session id to client so that in subsequent requests server can compare it with the local one. You can use GET or POST both, but in my opinion POST is better way here.
Go for HTTPS.
If you want to cache the credentials on the app side, look for keychain.

Drupal JSON API on iPhone

I am working with an app that is querying a JSON API on a server running Drupal. I used this tutorial and have changed the code a bit to work with my program, but every request just sends me to the not authorized page that the server generates. Any ideas why?
Why not use the drupal ios sdk? https://github.com/organizations/workhabitinc
I guess you haven't set the permissions in the Drupal service.
First go to permissions, and set the desired ones for the modules you're using (I guess you're using the default ones that are included within the services module).
Next, go to Site Building->Services, and authentication. Check if you have any authentication module set, and if so, add the methods that you're using to that key.
At our company we've made several apps which uses Drupal (but using XMLRPC instead of JSON). So feel free to ask everytime you need :)

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.

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

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.