Making itms-services link more secure - ios

I am developing an in-house enterprise application with iOS and am slightly concerned about security. If anyone intercepts the URL containing the IPA file then they will be able to download and use the file. Is there any way of making this more secure? I know I can put the link behind a login system but if someone copies the URL and shares it, others will be able to download.
http://example.com/
manifest.plist">Install App

The only way to achieve this is to have temporary credentials as URL Parameter! (Authorization Header don't work so forget about oauth).
The security (user, password, token, etc) has to come from the backend.
And more: http is not working. You need https (in detail TLS>=1.2) and trusted TLS certifactes (selfsigned not working).

Related

Rails public/private key authentication, but user has no server

I've built a JavaScript app that's powered by a Rails back-end. The JavaScript app (the built/minified version) is going to live on an S3 bucket.
The app Iv'e built is going to run on other people's websites, similar to Stripe (Stripe has you include this code in your HTML):
<form action="" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="api_key"
data-amount="999"
data-name="Stripe.com"
data-description="Widget"
data-image="/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
</form>
The difference is that my user will have no back-end, it's all handled by my Rails API. The end-user fills out the form on my user's website, and that data is POSTed to my API, not my user's API. My user signs up, posts a snippet with a script to my JavaScript app on their website, and then they have users fill out a form (again, like Stripe) on their website which sends a request to my API.
How can I manage authentication in this circumstance? The key that will be provided in the code snippet is obviously public, given that it's in the HTML on my user's website. How can I verify the request is coming from the correct person given the key? Should I look at IP Address and/or domain name that the request comes from?
Let's pretend your user's website is www.example.com.
You want to know did this request come from the real www.example.com ?
There are two possible solutions :
1- Certificates
If your user's site uses https(it has a certificate) the certificate identifies a unique site(that what it's for), on signup you can request that certificate and add it to your rails trust store, then in your javascript app you send the certificate on every request and your rails verifies it.
advantages
1- no backend needed.
2- more secure than a simple api-key, that's because an api-key could provide authentication but not non-repudiation which the certificate provide.
3-easy for your user(provided they already have a certificate).
disadvantages
1- too secure : you didn't mention that non-repudiation is a goal, if it is this disadvantage doesn't count.
2- might hurt performance : on every request a certificate is posted and verified, not only verifying a certificate is slower than verifying an api-key but sending the certificate on every request may heart bandwidth.
3- requires your user is using https, what if he/she doesn't want to use https for some reason ???
2- Setting a proxy
You store the api-key on the server and don't post it in the snippet and you assemble a simple backend that its only job is to send the api-key (some sort of a proxy).
advantages
1-not too secure : it provides the authentication you want without providing more needless goals.
2- good on performance : yes there is a proxy which may be slower, may be faster but that's faster than verifying a certificate and sending it on every request in my opinion.
3-simpler to program : I think assembling this backend is easier than writing certificate verification code in a Rails app.
4- doesn't require https.
disadvantages
1-more installation for the user : that's because they have to install a backend besides the include snippet.
2-the form data should be sent to this backend and then to your rails backend, so we have two round trips.
Now web servers (Apache,Nginx) can be configured to work as proxies but I don't know if they can be configured to send the api-key too.

How to protect JSON API from being accessed by anyone but my iOS client?

I have an iPhone app that uses a Rails server HTTP API. The API is public at this point - no authorisation is required to get the data.
Currently anyone can go to API's URL and download the data.
http://server.com/mydata
The data is not very sensitive. But I still want to prevent people from easily getting it. What are the ways of doing that? I do not want iOS app users to log in either.
Current solution I have
iPhone app adds a secret token to the HTTP header or query of the request. The data goes over HTTPS.
https://server.com/mydata?secret=my_secret
Is there a better approach?
You could try an approach where the client is only allowed X number of requests per time period (based on IP address or username)
HTTPS is extremely easy to man in the middle on a device you control. You can do SSL cert validation, but there is always someone out there with more time, so best off to handle it server side.
Distribute and use your own SSL certificate.
Apps that transfer sensitive customer data, like credit card and payment information, must be protected from man-in-the middle attacks. The best protection is a mutual authentication scheme, where certificates are exchanged to make sure the app is connected to a trusted server and to make sure the server is connected to a trusted app.
Then only individuals (who have presumably installed your application) have access. If someone digs through the code and gets the public certificate then they can impersonate the client; but at that point they win anyway and two-factor authentication should be explored.

How to secure my api using node.js and only my app is using this api

I want to create a iOS app, and I am starting to design a api using node.js+mongodb+express. I know people can use charles to set up a proxy and when user open the app in the iphone device, they can see the api requests in charles app. So people can use this api to do some harm to the app services or what. I want to secure my api. I won't open my api to others. So, I don't need oauth. What else I can do to secure my api? And if any tutorial is provided, that will be good.
Do it with https, just make sure your app stops working if the certificate is invalid.
Alternative:
Crypt/decrypt your http(s)-body before sending/after receiving with a global password (not recommended) or a public key on your phone and a private key on your application.
If someone gets that pw or public key, they can still manipulate the API.
What you want to do is use https with additional security.
First: In the app "pin" the server certificate, that is validate the server certificate in the app, this is quite common these days. AFNetworking supports this.
Second: Add a certificate to the app and verify it on the server. Now the server knows it is communication with your app.
Now both the server and app have assurance they are communication with authenticated end points.

Retrieve Client ios app certificate

I want to proxy traffic from an ios application to Fiddler (or Burp). It looks like the application sends a client certificate to the server.
I will need to retrieve this cert from the phone(it's jailbroken) and import it to my proxy. Is there a way to do that ?
The client certificate is used to identify the client. If the programmer of the app made his job well, you will face difficulties (hopefully). Likely, and most secure, the private key and identity resides in the key-chain. Less secure, it resides in a secured archive (.p12, .pkcs12, .pfx) in the bundle, whose password resides in the key-chain.
If the programmer did his job not so well, you might find the password of the secured archive in the clear somewhere in the apps binary (there're actually floating samples around which do exactly this).

ios generate application specific key

I'm working on an ios application without authentication. Now I would like to protect my server API from calls other then my ios application. A possible solution would be to have the application generate a unique key (based on the appname and the signing), which is not stored on the device since this is the main problem. I could think off an application logic that does some protection combined with some file encryption but the problem is that somewhere something is stored (ex public key can be stored in keychain but still not safe for my API-hackers).
Anyone any tips/advice on how I can handle this ?
thanks in advance
In short, there is no 100% secure way to make sure that the request comes from your application, if the key is available to the iPhone, it's available to extract from the iPhone.
You can make it reasonably safe by calculating a key runtime from info in the application as you say and communicate it over SSL, but a determined attacker can always reverse engineer the key generation too.
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use freely available tools for this, like keytool, and I think (but don't know for sure) that Apple includes a tool for this with the iOS SDK. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource. Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.

Resources