I have an iOS app that communicates with an Apache 2.2 server. I would like to restrict the access to several directories so that only the app will be able to access them (no browser access, no crawlers, etc). What are my options?


Run Apache on a non-standard port, like 8574. This first step will eliminate 99% of the "noise" you're expecting from robots and scripts.

The specific piece of configuration you want in Apache is mod_authz_host. It'll let you filter requests for access based on a variety of factors that Apache terms "environment variables," including the user agent. You could Allow from your custom user agent, then Deny from all.

CAVEAT: With all of that said, filtering based on user agent is not the correct way to implement what you want. Server-side controls are only the beginning of securing your application against unauthorized access. Authenticating to a web service (such as what you are developing) should be implemented using some kind of API key. Many REST APIs do exactly this. If you are not sure as to how to implement key-based cryptography, consult an expert (or face the consequences).

FOLLOW-UP: Implementing public-key cryptography is one of many ways to do the job correctly. Before you dig in, let me say that you're in for a world of hurt. Check out the indispensable "Everything you need to know about cryptography in 1 hour." Note that he says the phrase "consult a cryptographer" six times in the presentation. At its simplest, your server should be able to answer the following questions in the affirmative for any request:

  1. Can I guarantee that this request came from the iOS app?
  2. Can I guarantee that this message hasn't been tampered with?
  3. Can I guarantee that this user is who they claim to be?
  4. Can I guarantee that this user is authorized to do what they're asking to do?

As you can see in the presentation, even well-known APIs like Amazon's don't always get this right. I believe you need an expert on your team, at least to get this part of your application correct.

| improve this answer | |
  • OK, so the right way to do it, is to limit the access to the webservices using a public/private key? The app ALLWAYS sends the public key when it makes an request? Can you please give an example in a nutshell? – Valentin Radu Apr 29 '12 at 20:26
  • Pretty much this, though I'd add a bit: it really depends on how much you actually want to hide it. User agent check would be bare minimum since it can be easily changed by the user. An upgrade of that would be requiring custom headers to be sent by the user - while technically not harder to implement on their own, it would be a bit harder to do from within a browser (at least for most users). What you'll choose really depends if you really want to make it 100% to anyone not using the app or just have very hard to access from a regular browser. – Sašo Apr 29 '12 at 20:27
  • @Joel, I'm trying to learn myself, why would I ask a question on SO otherwise. Plus, the protected info is not vital (doesn't cost $$ if lost), still I would like to do my best to protect it. – Valentin Radu Apr 29 '12 at 20:55
  • Unfortunately since we can write a book on the topic, it's off-topic. serverfault.com/faq#dontask You are highly encouraged to learn all you can about cryptography and ask more specific questions once you've done some legwork! Check out the Security site at security.stackexchange.com – Joel E Salas Apr 29 '12 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.