How safe is it to use OkHttp3 for your REST API?
For example, if my website has some login/signup process, and my app sends requests with OkHttp3 client. How much can I trust that someone can't take his phone, plug it into Android Studio and look into the logs and find the links for all the requests I'm calling?
There's also the matter of decompiling the app, and easily accessing the base Uri I'm using in my app.
I'm not sure how OkHttp works, so can someone tell me about the security used in the client and how much I can trust it?
If a link is on the internet, then it's public. There is no point trying to hide that fact.
You need to focus on the securing the endpoint(s) the app is talking to for confidentiality, integrity and availability
You need to read up on Web security. Take a look at the OWASP Top 10 and related guides.
Why are you worried about your URL address? Whenever you expose an API on the internet anyone can find your API URL address. There are easier ways than reading logs of your app.
What is your exact worry? What do you need to keep secure? What is important for you?
Related
I am new to backend development and security. I have a LAMP stack setup on AWS and have a Android application with can POST and GET messages to this server. I want to now make the server more secure.
Currently I have no security in place and have no idea where to start. I tried implementing SSL with Apache but didn't have much luck.
Any links to tutorials or reading or any other help will be appreciated.
The first place to get started would be to ensure you are following the best practices for AWS: https://aws.amazon.com/articles/1233
Besides those on the list, setting up your firewall rules as tightly as possible, running something like fail2ban to prevent constant login attempts, running Apache in a chroot jail, and other things like that are all good places to start. Security is a never-ending process.
Setting up SSL (TLS) for your web service is an excellent idea and will prevent anybody from snooping the data going between your app users and your service. Getting SSL up and running can be a bit daunting your first time, but I would suggest starting with the Apache documentation http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html and talking with the representative at the company you purchased your SSL certification to explain everything they provide you. If you don't understand the basics of TLS, the Wikipedia article isn't a bad place to get a nice overview.
We have developed a service with REST APIs and an Android app that leverages it. We currently don't require our users to authenticate.
We would like to implement a simple mechanism to prevent the random person from invoking the APIs from outside of the scope of the app, mainly to avoid abuses that would spoil the data that we compute.
I stumbled upon this url where they suggest to have authentication enforced by having the server and Android client to share a secret and use that to compute an HMAC to pass along with the request. They claim that they use this approach in Amazon (I have no experience with Amazon AWS yet).
I'm considering to proceed as follows:
store a common secret in the Server and in the Android app (any good idea for obfuscating it, besides using ProGuard?)
Have client and server to communicate over plain HTTP (we don't need confidentiality yet and we will save some CPU) and use the HMAC method to authenticate the calls as "coming from a legitimate Android client".
From time to time we can update the secret (perhaps at each new version of the app).
If in future we will need confidentiality we will enable TLS for the relevant REST calls.
Do you think that this solution would work? Is anyone using something like this? Alternatives? Advices?
Thanks.
I am not a security expert.
Your solution sounds fine to protect you from "the random person", but you are still vulnerable to a dedicated attacker. Anything stored on the client can be dug out and used against you. ProGuard will dissuade a casual attacker, but against a dedicated attacker it's just a speed bump.
Nobody here is going to be able to tell you if that level of security is good enough, because it depends a lot on the specifics of your application. The final decision should rest with the product owner.
I have an android application. The application reads data from my server and displays them to the user.
Now, the question is: How to prevent someone from making a bogus app and asking my server to send data to this app?
This wastes both my bandwidth and makes use of my content while allowing people to create competitive apps using my data.
As you know, trying to prevent reverse engineering is like trying to stop piracy: impossible. Android reverse engineering especially it's like stealing candy from a baby.
Use API Tokens. Possible solutions:
HTTP Basic Auth example (only if you are using https)
Query Paramter (like https://example.com/resource?token=3786428762) (also only over https)
HMAC - sophisticated and more complex to implement, requires substainsial redesign of the backend communication, but the most secure
But mind you, either way you need to somehow hardcode a key/salt/hash/password in your app which can be reversed engineered one way or the other. There is no real (practical) possibility in Android to avoid rogue clients from accessing your backend (especially in rooted devices).
I would recommend HTTP Basic Auth since it's the best tradeoff in effort, usability and security (It's also used by the majority of public apis) It's very easy to implement since you only need to send a hardcoded http header, it's supported by practically every http server and it does not change your API and pollute it with query parameter and it's also reasonably secure if used over https.
Make the server require an API key and obfuscate the key in your code, see this answer: Best Practice for storing private API keys in Android
If you use http server, you can use http auth basic
Basic access auth
You could use something like reCAPTCHA to verify that the client is not a bot.
We have an android and ios app which sends data and commands to a server with http webservice. How can i prevent the possibility, that fake-clients also can send something to the server? How can I determine serversidely if the data/command really comes from our apps.
You cant really prevent it. There are several techniques to make it harder for people abusing your services.
A simple check can be to check the user agent calling your webservice. Another pretty common one is to use a simple authentication via user/password authentication on your webserver. The username and password will be embedded into your app.
If you have enough time you should think about using a combination of this two methods plus authentication with a embedded ssl certificate. You simply could add this to your project and if someone really want to abuse your service, he have to extract this certificate atleast form your application.
There are some other useful techniques but you cant prevent reverse engineering or network sniffing.
Sincerely,
fuxx
The most robust solution is not to try. Techniques like DasFuxx's answer suggests can make it faintly harder, but someone can always decompile your application and get whatever secrets you have embedded in it.
Instead, follow the rule of multiplayer game development:
Don't trust the client.
Don't think about your application as the user interface. Think about your network protocol/API as being the user interface; then design that interface so that it cannot be abused.
It may not be possible to do so completely, but insofar as you succeed, you have true security (rather than fighting the same losing battle as DRM systems).
I would implement oAuth. See the following link for more information on how to implement such a solution.
You can't. It's that simple...
I want to develop an android app for my website. One way of doing it is to have an API for the site, and let the app use that API. However i want this API to be used ONLY by my android app, I don't want any other client to be using this API.
Is there a way to ensure this?
I can think of one way of doing it: put a secret in the app and let the app pass this secret always to the API. But i am not sure how secure this approach would be because any packet sniffer can easily sniff the parameters and hence the secret. Any other suggestions?
I think this is something similar to a question I answered a few days ago.
Securing a REST API from Android
Namely, find a way to authenticate all of your requests using a shared secret.
If you sign both the path and params with a secret, then there should be no way for someone to forge requests.
Finally got hold of the answer from the android developer's blog article.
The short answer is no, sorry. If someone really wants to exploit your site/api/device/program/insert anything here and they have the time and resources then they will.
To directly answer your question, putting a key in your app isn't secure as anyone can decompile the app and try to reconstruct the key from the source files, they don't need to sniff traffic.
Correct me if I'm wrong! Packet sniffers can only be used with unencrypted WiFi and in (now) rare network configurations (a router or a switch prevent them).
For serious matters, you should consider secured connections (https).
That said, for standard content, I feel that a passphrase is secure enough. Many popular web apps don't use more than a cookie over http to let you log in, which is exactly what you're proposing.
I struggled with this issue and I actually ended up implementing a version of OAuth for securing my API. It can be difficult if you don't to launch a browser to do the "login" part of OAuth. I baked the login right into my my app and actually implemented the token exchanges under the covers. Too much involved to post the code here, but it works great. Obviously HTTPS is desired for an additional level of security.
If you could get some kind of signature back from package manager of your own app, you could use obfuscation to hopefully make it much more difficult, and have the signature/hash of signature from package manager be the key for your HMAC-SHA1.
Might have to try this ( How to get APK signing signature? )
If you did that, it would make it more difficult to use. Obviously, it could still be decompiled, but if they re-compiled it w/ debugging etc, it would have the wrong key. They would then have to actually make their own package manager on a rooted device to get the signature.