I am going to make an application (iOS and Android) that will use a web service that I am developing. I will use HTTPS and SSL so that the data sent from the app to the server is secured. However how do I stop (or make the life of people who decompile the app hard) "hackers" from decompiling the source code where the URL is written?
I don't want other people to make an application that use my data.
The users of my app will have to register and login in order to use it. I have read something about authenticating the users and pass a key back (the way Facebook does). However wouldn't this mean that a "hacker" could sign up and then use the same key? Would you need to track the usage of each key to look for irregular use?
The server technology is either Java EE or Scala (Lift).
First: There is no 100% security for anything you run on a device that is not under your control (like iOS and Android devices in your case).
You could make "abuse" harder by several measures:
issue a session key after a successfull login with a time-limit so a new login needs to happen after a certain time has passed by
issue an interaction key for every communication step which gets invalidated right after one usage
when a successfull login happens terminate any other session associated with the same credentials that might be active before that login
"throttle" usage (might be impossible depending on the specific application)
IF you really really want to make it very hard you can issue a device-specific client-certificate and use cert-based client authentication (defined in SSL standard) - you can invalidate the cert associated with the device if you see abuse without harm for the legitimate users of other devices...
This is more-or-less impossible. You can use bytecode obfuscation to make decompiling harder, but anyone who tries hard enough can see what the code is doing.
If you are allowing access to the data to people that you can't trust, then the only things you can do are to
ask nicely (please don't abuse my data)
authenticate users so you can monitor individual usage, and maybe apply usage or rate limits (like Twitter does)
make people sign a legal agreement (unlikely to attract many users unless your data/app is very valuable to them!)
Also consider whether you can do more server-side processing so that less raw data is sent to the client. I don't know what your data is like, but taking the example of maps, if you send a pre-rendered bitmap rather than some lat/long vector data, then extracting anything useful is much harder work.
Related
I need to add something that generate an activation code in my android app so the app features should work only if the app is activated. what is the best way to do that ?
If I understand the question correctly, what you want to achieve is technically impossible.
Any functionality your app has is already there in the app, downloaded to the client. A user can use a debugger to disassemble the app file and change your source code to either not require an activation code or accept any code (whatever is easier, but both are possible). Anything you give to a client should be considered as being fully controlled by the client, any logic in there can be changed, secrets can be seen, etc.
This may not be straightforward, especially if you use some kind of an obfuscation, but it will always be possible. The question is only the effort needed.
And the effort is key here. In some scenarios, protecting low-value resources, it may be good enough to deter the lowest profile attackers. It's always about risk and the cost of protection. But you need to be aware of the above, that the logic in an app cannot be protected.
So if you want to protect your stuff, you have a few options for different scenarios:
Have two separate apps, one free without paid functionality included and one paid. Users can use the free one and then buy the other if they want.
Have paid functionality served by a server. If critical business logic is on the server side, you can really enforce access control rules and you can maintain control over who has access. This may have serious implications on your app architecture and functionality though.
If the value you are trying to protect is low, you can go for obfuscation and access control logic in the app as mentioned above, but you need to be aware that this can be cracked relatively easily, especially on Android by changing the apk.
I believe you cannot do this with just your app, you definitely need the help of server which would generate an activation code for you and match it with the logged in user. Once the generated activation code is passed on to the user via email or any other means, then you can match the activation code given by the user and then match with the one in the server and if they match, let them use the features.
I hope this is what you want. But I might even be dumb enough to misunderstand you. Let me know if this is what you want.
I am a web developer and in web development we have been taught to do both client side and server side validation. In Android programming I am doing the client side validation and showing messages using Toast. After that sending data to web services,
1) should I still do a validation (like password field has min of 6 characters, alphanumeric etc.) in web services.
What are the best practices with respect to validation in Android development?
Yes, You should do validation from server side. then the question why comes
Client-side validation is always in the sense of providing a better User Experience (UX), so the user doesn't have to submit and reenter information simply because a value in a form isn't valid - it makes things more dynamic.
What could a user do if you do not server-side validate? Anything, depending on how you use their data. You could be allowing users to drop entire databases (or worse, leak them), modify anything they like (or worse, read anything they like. Directory traversal flaws are extremely common entrance points for naughty people), and elevate their privileges at will. Do you want to run this risk? Not validating user input is like trusting people and not installing locks on your house.
Yes, you should definitely!
Imagine you add other clients, other than Android, to communicate with your application. Then, by server-side checks, you have the insurance that the checks are consistent. Otherwise, consistency is much harder to achieve.
For example: You add a Website as an additional client (beside your app, like some messangers do), and add checks on the client-side by JavaScript. The user disables JavaScript and puts trash into your database!
Another example: You add a iOS-Client. Your password-requirements change from 6 to 8 letters. Now you have to modify and deliver 2 clients, while with serverside-checks. you only have to update your webservice.
So you get safety for more clients!
I wish to connect to a Mysql Database with Java without revealing the password to anyone that may decompile my code? I can efficiently connect to a database, but my ways will openly show my password in the code :( and wish only a response on how to hide the password. Thanks is advance, Josh Aurora
OAuth allows client connection without storing credentials on client ( used widely on mobile devices or to identify tweitte applications ). It also allows to remove access permissions from rogue clients. But I doubt that mysql suzpports this directly,. so you will have to wrap your database with some kind of service layer. One of usable imaplementations of OAuth:
http://code.google.com/p/oauth-signpost/
(IIRC, used by Qipe )
Assuming that the database which will be accessed will be on your machines, two things that come to mind:
Set up a small secure REST service (as shown here) which will, upon a certain request with certain credentials, pass the password to your database. This however might be an issue if your application is sitting behind some corporate firewall since you might need to add firewall exceptions, which is something that not all administrators are enthusiastic about.
You could use a mix of Cryptography and Obfuscation to encrypt the password to the database and then obfuscate all your code.
As a note though, either of these methods can, in time be broken. This is basically the rule about all security related software.
If it where up to me, I would go about this problem using the first approach and make sure that the credentials through which the service is accessed are changed often.
However, databases which are used as part of a client solution contain pretty sensitive data which is in the client's interest not to tamper with, so the client will most likely not mess around with it, he/she will be happy as long as the system works.
If on the other hand, the database is not deployed onto one of your machines then you can't really do much about it. You could recommend that the server will be stored on a remote machine with access only over the intranet, but other than that, I do not think you can do much about it.
I need to be able to transmit data from a Flash browser application to a PHP file on a web server, both securing and validating the data whilst and at the same time trying to prevent unauthorised creation of the message. (I want to try and ensure that the message comes from the application, not a user sending a message via another means).
In a C++ application I would Salt the data, and send the hash of the data along with it, and then validate the hash against the data to ensure integrity and source.
However, in Flash (& Java), applications can be decompiled so that the source code is viewable. So if I used this method, someone could (relatively) easily find the salt, and then create a 'valid' message of their own to send outside of the application.
Is there any way I can 'hide' this salt code to help secure the transmission? Yes, I know there are code obfuscators, but they don't fully hide the code, just add another layer.
Or is there another method entirely that could be used to transmit data and validate the source & content at the PHP end?
No matter what you do, the code to do it will be there in the client, and all you can do is obfuscate. If you, as Tomasz says, were to have the client authenticate with the server and then receive a salt (or a key from a asymmetric key-pair) you still need to have all the code necessary to connect to that server in the client. So by design, no matter what you do, all the ingredients to do so has to be in the client, and thus on your "hackers" computer. It's just a question of much harder it would be for a hacker to understand it.
It's the same for all kinds of clients, no matter what language they're written in. If a DVD player can show a decrypted DVD disc on your TV, it has to have the key to decrypt it in memory, which you can find. This is why no-one has made perfect copy-protection :)
EDIT:
As all the others are saying. Off-the-shelf obfuscator is probably the best way to go, and you could make the client jump through some extra hoops first aswell.
EDIT2:
Turns out I didn't understand Tomasz correctly. If the user himself has the key to authenticate to the server in order to get the hash, that will indeed authenticate that the message was sent from the user, but still not from the application. If this is a matter of avoiding cheating then the hacker is probably already a customer (buying a product or making an account). If what you want is to authenticate the user, then it's a completely different matter, and that is quite possible. (with it's own problems of-course)
There's no truly secure way to protect programs that run on the client. (C++ can also be decompiled by the way.) It's always going to be possible for users to run clients that have been hacked, and any encryption key will have to be present in the code in some form. You may be able to make it more difficult for casual hackers but that's it. Whatever you implement will amount to another form of obfuscation; you may as well look at the off-the-shelf obfuscators.
Perhaps first authenticate with the server, get a salt key from the server, then use it? This way users wanting to fake messages even if capable of decompiling the app would have to authenticate also.
Other than that - at some time you always need the password, hash, key (or whatever is needed to encrypt or validate data) available to the application and either you get it first from your server or embed in the application, which would be recognizable by decompilation.
EDIT
As others have pointed there is no 100% security, everything can be hacked, the point is to make it not too easy, to prevent casual hackers, that's all. So as Jim stated an off-the-shell obfuscator may be the best compromise.
Here's a use case:
I have a desktop application (built using Eclipse RCP) which on start, pops open a dialog box with 'UserName' and 'Password' fields in it. Once the end user, inputs his UserName and Password, a server is contacted (a spring remote-servlet, with the client side being a spring httpclient: similar to the approaches here.), and authentication is performed on the server side.
A few questions related to the above mentioned scenario:
If said this authentication service were to go down, what would be the best way to handle further proceedings? Authentication is something that I cannot do away with. Would running the desktop client in a "limited" mode be a good idea? For instance, important features/menus/views will be disabled, rest of the application will be accessible?
Should I have a back up authentication service running on a different machine, working as a backup?
What are the general best-practices in this scenario? I remember reading about google gears and how it would let you edit and do stuff offline - should something like this be designed?
Please let me know your design/architectural comments/suggestions. Appreciate your help.
The simple answer is: Don't let the authentication service go down!
Make sure your authentication service is running in a clustered, load balanced environment behind a virtual IP. That way, you can avoid downtime in the event that one of the individual servers goes down. This goes for not only the service itself, but any data sources that it relies on.
Obviously no system is completely fail-safe, but you should be able to get your uptime close enough to 100% that there is no need to build a "limited" mode for the desktop client.
Should I have a back up authentication service running on a different machine, working as a backup?
Yes! This would be the best solution. The issue should IMO be dealt with on the network/infrastructure level, not on the client.
If there are useful parts of the application that could still function with no network access (e.g. router down, NIC goes pop), option 1 might be considered. Offset the amount of work necessary against how likely this is and how critical your app is.
If said this authentication service
were to go down, what would be the
best way to handle further
proceedings? Authentication is
something that I cannot do away with.
Would running the desktop client in a
"limited" mode be a good idea? For
instance, important
features/menus/views will be disabled,
rest of the application will be
accessible?
Running the desktop client in a limited way is a very good idea. Imagine if you were unable to write an email, perpare attachments, or do anything in an email client if you were not logged in. A good user experience demands the ability to work offline.
Should I have a back up authentication
service running on a different
machine, working as a backup?
This has been answers very well by others already although I don't agree entirely with dbyrne. Even though all your networks and servers may be running fine, downtime is inevitable and the communication between the desktop client and the server will not always be perfect.
If said this authentication service were to go down, what would be
the best way to handle further
proceedings? Authentication is
something that I cannot do away with.
Would running the desktop client in a
"limited" mode be a good idea? For
instance, important
features/menus/views will be disabled,
rest of the application will be
accessible?
Is the client useful without the server? Are there things the user can do? If so, do you want the user to be able to do these things without authenticating? That's the answer to your question.
It isn't clear what you mean when you say: "Authentication is something that I cannot do away with." what you mean. Do you mean that there are some features that require the user to be authenticated, or that it is a requirement imposed by someone else, or ? (Why can't you do away with it?)
Should I have a back up authentication service running on a
different machine, working as a
backup?
How useful is your client in the situation above? If it is very useful, then you can base this decision and how much to spend on maintaining a backup server on how valuable the authenticated features are alone.
If your application is useless without authentication, then base your decision as to how much to invest in a backup authentication server on how much it costs you when your users cannot authenticate.
What are the general best-practices in this scenario? I
remember reading about google gears
and how it would let you edit and do
stuff offline - should something like
this be designed?
If there is a way to keep useful data offline, I think that's a good idea, but I am biased against keeping my information in the cloud where I can't control it or back it up. It will cost time and implicitly money to develop the ability to do both online and offline versus just one of the two. This is a judgement call on how valuable the application is to your users when offline.