I have an iphone app that retrieves and send data to a server that uses python.
What measures could i take in order to prevent security risks?
I an not handling extremely sensitive data but i wouldn't want people sniffing the contents.
Is using SSL enough to prevent most risks?
Thanks
SSL should be sufficient. It's also a good idea to store the user's password (if you need one to login) inside the Keychain. Btw, don't send anything to the server in a QueryString, always do it with a post, otherwise the SSL won't do much to help you.
If you don't have super-sensitive data, you can also use HMAC messages in order to query your server. I've done this with several projects before.
The message sent to the server may be a little more heavy-weight but is a viable option if you don't want to go with getting a SSL certificate.
Related
I am working through some security concepts right now and I was curious if this method has been tried and/or if it is safe taking into consideration "Brute Forcing" is still possible.
Take for example a Microsoft WebAPI Template in Visual Studio where you access a endpoint using a "GET".
The Endpoint would be accessible by any user/application
The String value that a user/application would get from this endpoint would be the password they need, but encrypted using a "KeyValue"
After a TLS Transmission of this Encrypted Value, the user/application would decrypt the String using their "KeyValue"
Is this a secure practice?
Thanks for indulging me and look forward to your responses.
EDIT: Added Further Clarification with Image to Help Illustrate
Suppose the following 2 Scenarios:
Communication between Server and Client
a. Your Server serves the Client application with an encrypted password.
b. The Client can request any password.
c. The passwords are encrypted with a shared Key that is known by both server and client application
As James K Polk already pointed out:
A knowledgable Attacker can and will analyse your deployed application and at some point will find your hardcoded decryption key ("KeyValue"). What prevents him from requesting every password that is stored on the Server?
Rule of thumb here would be: "Do not trust the client side."
Communication between Server and Server
a. You have 2 server applications. Application A is acting as some kind of database server. Application B is your Back-End for a user application of some kind.
b. Application A serves paswords to any requester, not only Server B. With no type of authentication whatsoever.
c. Confidentiality is guaranteed through a shared and hard-coded Key.
I think you are trying to overcomplicate things hoping that no one is able to piece together the puzzle.
Someone with enough time and effort might be able to get information about your server compilation and/or be able to get the Code of Application B. Which again defaults in the scenario of 1. Another point is that there are enough bots out there randomly scanning ips to check responses. Application A might be found and even-though they do not have the shared key might be able to piece together the purpose of Application A and make this server a priority target.
Is this a safe practice?
No. It is never a good idea to give away possibly confidential information for free. Encrypted or not. You wouldn't let people freely download your database would you?
What you should do
All Authentication/Authorization (for example a user login, that's what I expect is your reason to exchange the passwords) should be done on the server side since you're in control of this environment.
Since you didn't tell us what you're actually trying to accomplish I'd recommend you read up on common attack vectors and find out about common ways to mitigate these.
A few suggestions from me:
Communication between 2 End-points -> SSL/TLS
Authorization / Authentication
Open Web Application Security Project and their Top 10 (2017)
A client asked me to do a back-end server for its iPhone application and want only users who bought the application to be able to call the server.
The problem is that he doesn't want to add a login system to the application, so that it seems to me there is no completely safe way to prevent someone without his application calls the server.
In any case, even if it can not be completely prevented, it would be sufficient to make it difficult to access servers without the application.
What is the best way to achieve this? Again, I do not need to fully protect the connection, there is no transit of sensitive information, I just want to make things a little more complicated for people who want to take advantage of server without paying the application.
The idea that seems most simple is to encrypt the data with a key stored within the client and known to the server, so that the message can be decrypted only decompiling the code and finding the key (of course instead of a key you could put a list of keys, which change every 6/12/24 hours).
Could this be a reasonable solution?
This will never be possible. Welcome to the nature of the client-server architecture. You can never trust the client. Just make sure the functionality you are exposing is safe.
well if its a paid app you could release the app for free with all the functionally locked down until a user does a in app purchase and then you could verify the receipt on your server therefore proving that the device is a iOS Device?
sharing a key between the client and the server seems to be a good way to go. But instead of depending on the stored keys only, try combining them with a Unique identifier, such as UUID and send it to server both with the combined key, and the UUID itself.
At that point users UUID will be his identifier (username) and the combined key will be his token (password). And this will be a login-like mechanism.
An SSL connection is not enought to prevent other people from getting the URL for the requests? Or even better using an SSL connection with a basic auth?
I want to encrypt some json from a server and then decrypt it on the iphone/ipad. What are your thoughts on this? What is the best approach to this? Should I scrap this idea and just go via SSL?
Save yourself a lot of trouble and just use HTTPS for all server communications.
As stated above one way is to do everything over https.
An alternative I can think of is the following:
Generate an symmetrical encryption
key per session/login per client on
the server
Send that key to the client over
https
From there on encrypt all the data
you send to the client with that key
The client can then decrypt the
encrypted data
I don't have enough knowledge about https. I often read that is heavy on the resources of the system, but since I have not made or read some good benchmarks I can't give you a rigorous argument for or against it.
The implementation I proposed require a little bit more coding, but you can tailor to your encryption needs.
I think ultimately your decision should be made based on your usage scenario, if you sent very little data, not often to a few client application, you can't go wrong with https. If your expected encrypted traffic is high, the alternative solution might make sense.
We have an iOS app which interacts with various webservices at the backend. The backend however wants to validate that the request coming to it is from our valid iOS app and not from a replay attack or a "man in the middle" attack. We are eventually going to have all our calls changed to https. However, is there any way the backend can validate the request is coming from our legitimate app? We were thinking of using cryptographic nonce with every request, but it would still be prone to "man in the middle" attack. Is there any certificate exchange that can be used between the iOS app and the server?
TLS and SSL support client authentication using certificates. NSStream might support client side authentication, but I have not been able to find a way to do it without dropping down to using OpenSSL for the actual implementation.
Addition:
ASIHTTPRequest supports client certificates since version 1.8, so no fuss in implementing it.
what about using a private/public key scheme so that the iOS app can sign every request it sends?
if private/public key scheme may sound scary, the same idea of "signing" your requests can be easily implemented by hashing your crypto nonce by using sha1, sha2 or other cryptographic hashing algorithms. this would be pretty easy to implement (implementation are readily available), fast, and would ensure a higher security level.
I would suggest to use OAuth. It well known and understood and pretty much secure, and in the case that someone gets your token, you can issue a new one with an app update and revoke the old one.
This is a general http problem, not just an iOS issue. In fact, it's the very problem https is designed to solve, or at least mitigate. You can sign the request, use HMAC to authenticate the message, use digest authentication, and so on, but as long as you're using http, a man-in-the-middle attack cannot be easily detected. Spend your time moving to https as quickly as you can instead.
This problem is impossible to solve absolutely. Anything you put into your scheme can be ultimately broken by jailbreaking the phone and running the client in a debugger. Of course, that doesn't mean you can't make it more difficult to spoof your client using client certificates and whatnot, and you should. But if for example the security of financial transactions depend on your app not being spoofable, that would be bad...
I have written an iPhone application communicating with a server. The app sends a message to the server and prints the result.
Now I have a question: Is there a way to know if the message sent to the server came from an iPhone?
I am asking this because I want to prevent attackers from sending messages from somewhere else and flooding the server.
If you use in-app purchases, then there is a full authentication chain that validates device X purchased the app. You're server can track this and then only give full responses to previously authenticated devices.
This approach also keeps pirated apps pretty much out of the picture.
This approach wouldn't stop a concerted DDOS attack, but your server can at least ignore non-valid clients and thus reduce its workload significantly. Since your server is ignoring invalid requests here, it also makes it less appealing to potential non-device users and the illicit user would probably only attack you if they disliked you, as opposed to them just bogging down your server for its free web services.
If you don't use in app purchases, you could set up your own authentication process and give a token to the device and have your server remember said tokens, and then later only serve valid responses for requests that had the said token (appropriately hashed and salted). This approach would not stop pirated apps from using your service, but would effectively stop non-devices from using your web service (again, except for concerted hacking efforts).
An even simpler approach is to have an obfuscated request format that would take a concerted effort to reverse engineer.
In all of these approaches, you might have to monitor your server for unusual activity and then taking appropriate steps.
I would encourage you to match your efforts to the expected risk. You can spend days, months, even years, properly securing an app, make sure the cost is worth the reward.
You could do some form of authentication, encryption or fingerprinting, eg. using SHA, MD5, etc. That way you could make it difficult (but not impossible) for an attacker to abuse your server.
You can't tell it's from an iPhone until you have received and examined the connection on the server. If you do that, you have already opened the possibility of a DOS (Denial of service) attack due to connection exhaustion.