I came across a few tutorials online explaining how to connect to MySQL from an Android app, but they are a bit surface.
If I just write SQL and send/receive it in a POST, it seems problematic for a few reasons:
1) Hardcoding SQL with obvious issues there
2) Security concerns about sending sql - is that safe to send that request? or should it only be done via SSL?
3) To connect to the db, in order to insert things, I need to have the db connection info inside the app - is that safe? Can the code be read by someone hacking the device and the apps?
What is the best way to go about connecting and using a remote db from an Android app?
Thanks!!
Wrap everything in an API and manage authentication either with encryption with public/private keys or with a token-based system. You should never, ever, ever accept raw SQL in any way, shape or form from any device or site. Most often if you need live, remote data to run you should reconsider your application workflow and work off slightly stale data or provide the information in the background due to the possible spotty connections. Hitting even an API can be a costly endeavor so it shouldn't be something that has to occur frequently.
To incorporate some of the ideas above you could a couple things. For the public/private key read up on http://en.wikipedia.org/wiki/Public-key_cryptography. The basic concept is you store the public key on the device then negotiate a private key after the installation of the application that is also stored on the device (although not coded into the application). This key is the one you have to protect so it should be negotiated on installation and stored with the lifecycle of the application. You could contact an API with a unique hash of the device (say the device ID) and a password that the user could set. In that way if the data is wiped, since the password is stored on the server you can validate that a request to generate a new key is valid for that device ID and also protect against attackers trying to disrupt everyone's keys.
Obviously this is still susceptible to someone intercepting the initial request but if you are using HTTPS (which you should) then it should mitigate most of these issues.
You have to make sure an attacker just cant send in random device ID requests to generate new keys as it would disrupt the actual user's device of that hash, which is why the password set is important. Of course they could also do this against device IDs not currently registered but you could easily implement throttling and blacklisting against the initial API.
There are many things you can do but depending on your sensitive data it may be overkill. You'll have to make that judgement call and figure out who you are trying to protect your data from.
Use a webservice through which to communicate with the database. End User clients generally do not communicate with the database over the internet. Multitier_architecture
Related
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.
I see many people trying to connect an Android device directly in a database like SQL Server or MySql and the answers are always the same: Use a web service. Why not connect directly an Android device with a database? I'm using a local network with my Android application.
There are a number of reasons.
Security- If the user has direct access, they can get anything from your database. Plus they will have a password into your database. As a result, if the SQL server you are using has a flaw, then they can exploit it. Also, if your permissions are set up wrong, the could wipe your database.
Speed- If the users frequently use large queries, then it can bog down your system quickly and needlessly. If you go through a web interface, you can throttle it.
Accessibility- Web queries are supported by almost everything. It requires special clients to access SQL databases directly.
But if you trust your users completely, have the right libraries/drivers, then you could allow direct querying, and it might even be a bit quicker.
If your app connects directly to the database server you have to hardcode username / password which is very insecure. With some tools an attacker can decompile your apk and can access username / password in this way and can connect to your database with read (+write) access without using your app.
Another reason not to access database directly
Problem If you changed database architecture.
you have two solutions.
1- in direct access you will need to update every Client app
2- using service you only need to upgrading the service.
The reason is the connection
You're not sure how many time you'll have to maintain this connection, if it's stable and if you're not going to lost it
Secondly, web-service are optimized to retrieve an information and serve it beautifully with standarts. You can also cache the informations to spare your DB
I am working on an applikation for Android platform. The application uses heavy amounts of HTTP calls to my webserver. This works out verry well but im in need of assistance in securing my calls and webserver.
I know that i can use SSL through Https to encrypt my connection both clientside and serverside, this is not a problem and will ofcourse be done when launching the application. But what would the most secure way be to have a session for the logged in device?
Ive thought about making a mysql based session system containing the following rows
id - sessKey - sessCont - sessUid - sessTime
sessKey will be a random generated 32 bit key. sessCont a JSON array of the stored informations and sessUid will be the user id of the user signed on. sessTime would contain a timestamp.
This session will be set on login and the phone would then recive the sessKey + sessId. When making calls the key will be changed and returned to the phone again. If a call is 10 minutes later than the latest call the session will close down and a new one will have to be made.
Yet i keep seing ways of compromising this approach, as well as i can with all other approches im able to think off.
How would i manage to make the best possible security and session control from my phone to my serverside script?
Thanks in advance.
Jonas
Alright numbered list time...
If you're using an SSL connection a good portion of security is already on your side. You can cross sniffing off your list of vulnerabilities.
Most of the leftover vulnerability will be on the user end, can hackers monitor the hardware on the user end and grab a session information after it's been transferred to the user's hardware, which in this case is an android phone. App data is protected from other apps so unless you, the developer, or your user is doing something insanely reckless it should be secure.
Which leads me to #3, all the rest of the security really lands in your lap as the developer. If you have cross-site scripting (XSS), the session IDs can be guessed easily, or you are vulnerable to session fixation, or your session ID storage is weak (SQL injection?) then you've effectively undone all the good work you did with every other measure of security.
In the end there are always ways to hack a system, but if you follow those three steps you've done everything you can do in order to prevent hackers. The rest unfortunately lies in the parts we can't touch; Android operating system, cell phone networks, user's common sense.
P.S. The most secure method would probably be to trash the session idea. Store the user id (a number that could mean anything), and a md5 encrypted version of their password. Be sure to add something funky so hackers can't just look up the reverse of common passwords. (IE. theirPassword+userid+HACKTHISSUCKERS) and even if someone goes to an md5 reverser they won't be able to undo your hash. And then every time you make a request to your server, do it over SSL and when the authentication checks out, send the info. Secure SSL connection, secure md5 passhash, no security leaks.
Even if a hacker somehow found what your app was sending to your server; a number and a undecipherable hash. The only way they could find out what your app was sending was if your user was being negligent and allowed their phone to be connected to the hacker's hardware that was actually capable of intercepting POST data before it was sent over the SSL connection.
I need to make requests to a web service via android application.
The webservice can be designed as needed.
It seems to me that no matter which approach I will choose, someone who wants to hack it, will just need to reverse engineer My android appliaction code (which isn`t very hard) and
could see exactly what I do, wheather I encrypt the data, use hardcoded Password or any other solution for that matter.
Is there a solution which will be 100% secure?
There is no 100% secure, all you can do is make things harder for your attacker. Things you can consider:
Encryption - Passing your requests over encrypted channels will stop
basic sniffing (this can be countered with MITM)
Obfuscation - Make your intent harder to understand when they do decompile your app
The second part to this is mitigation - the ability to notice when your app has been compromised and deal with it. A typical way of handling this is to assign a unique token to each client on first run then pass this as an argument on each call to your service.
This way if somebody decompiles your app and figures out how to call your service you can at least start monitoring where the abusive requests are coming from and also monitor for suspicious behaviour (i.e. multiple requests from the same key in a short period across different IP addresses). From there you can start blocking keys.
You're worried about "hacking ", but the base of any security discussion is defining the risk.
What are you trying to protect against?
For example, are you trying to protect against an attacker to read someone else's connection to the server?
A simple and secure solution for this scenario would be to use an asymmetric key exchange for your symmetric encryption keys, or use an existing protocol that does this (e.g. HTTPS). embed the server's private key (or certificate if using HTTPS) to also defend against man-in-the-middle attacks. Reverse-engineering your app won't help an attacker here.
I'm building an Android application that needs to communicate with a MySQL database. The application isn't meant to be published, and I want the application to be the only thing allowed to interface with the web service I'll create for DB access.
I've been thinking how I can secure the system, and this is the idea I've come up with. I'd appreciate any feedback or other ideas. Surely there is a method built into Android that I am unaware of.
My thought is to give the web service a GUID. Each time a call is made to one of it's public methods, the web service matches its GUID with the GUID given to it by the Android application. If the GUIDs do not match, the web service refuses access. In short, my system has a 128-bit password.
If you trust the individual to administrative your database then everything should be fine. The most important change is that all of this communication must be done over HTTPS. If a hacker sees this traffic your database will get hacked.
I would still use a username/password combo to access the system. I recommend using the existing mysql.users table with the MySQL password() function. This GUID sounds identical to a cookie, and I would seriously consider using an existing session handling system such as php's session_start() instead of rolling your own. Re-inventing the wheal is bad, especially when it comes to security.