How can you protect info contained in an APK? - java

I assume someone's built an APK decompiler..... What's the best practice to secure sensitive info (like auth parameters for a backend database)? I suppose some kind of middleware would work but that can't do good things for speed. What's the "right way"?

If you're writing an Andoid app and using AWS, strongly recommend you check out:
https://github.com/apetresc/awskeyserver
Author uses the AWS IAM (Identity and Access Management service) with Google App Engine to successfully protect authentication parameters. I imagine IAM will eventually be included in AWS' Android SDK but until then, this is a great option.

It's difficult to reverse-engineer Dalvik byte code; my understanding is that there's not a simple mapping back to Java byte code, much less to Java source, particularly if it's gone through ProGuard. However, auth parameters are usually data, not code, and that can be snooped for rather more easily. Moreover, someone interested in breaking your credentials has lots of other means of attack, including packet sniffing, that don't require recovering your source code. The comment by Anon is exactly right—don't trust the client.
As to best practices, you can use a public key encryption system, get credentials from the server, etc., to avoid putting sensitive info into the .apk file. Don't trust obfuscation or obscure byte code to keep your secrets. They won't.

Related

Checking password in java code (security concerns)

I am writing a small webserver for my house to play around with a few java API's I want to know better. This web server will eventually hold personal files and pictures.
I did not feel like setting up an LDAP server for authentication and was wondering how bad would it be if i just had the java code check it directly?
As long as you take proper precautions not to distribute or publish your source code, having a hardcoded password is most certainly safer than having a network service validate it. There are two problems, however:
Keeping your source code secret may not be too hard, but you can easily forget that you hardcoded the password in the future an become careless about the source. You may want to copy it to a friend, or publish it on github.
Having the password hardcoded means that someone that compromises your code may easily learn the password. A tried-and-true network authentication solution will not be ridden with vulnerabilities - your code almost certainly will.
A potential alternative you should consider is to keep a plain text file with the password, and read it as necessary. It mitigates (but doesn't eliminate) these two issues, and will also allow for a bit more security if your OS supports the proper file permissions and user privilege separation.
As always, avoid using a password repeatedly for different services. Since you'll have untested code facing the internet, remember to implement proper OS-level counter-measures.

How to achieve some measure of "privilege separation" with Java web-server?

I'm trying to be proactive around security on my Jetty web-server boxes -- especial with regards to storing SSL key information although I'd like a generic solution. Apache uses privilege separation so that it starts as root so it can read the protected SSL key files (and other secure configuration) and then switches to some common user to actually server HTTP requests. But Java has no mechanism for doing this.
Any recommendations around how to achieve the same level of security in a Java web application? My requires include:
Secret information should only be readable by root.
Any passwords which unlock keys and the like should not be configured into the code so that someone with the same user level permissions as the server can't get them easily.
I'm running under Amazon EC2 so I want the security to be as automatic as possible -- i.e. no interactive password entering by operators.
One possibility would be to use ~LDAP to separate the secret information from the application and only bake the LDAP access username/password into the application. But I'm looking for a better solution.
Thanks for any information.
Edit:
I'd hoped for solutions that covered SSL but took into account other secrets that I wanted to limit access to. I did not make that clear enough in my initial post.
The apache technique you described is provided by the optional jetty-setuid features.
See http://www.eclipse.org/jetty/documentation/current/setuid.html
As soon as you bake anything like a password into source (which is stored on disk), you've circumvented security. So, storing the information in LDAP isn't going to help.
I'm not convinced the setuid feature is going to help either, in that it is there purely for accessing ports in the networking code, and might not do the setuid at the correct time (after opening the SSL files). Of course, you could test that by protecting the files as root and see if it can open them...if so, you're golden and Joakim's answer is the best option.
What we do is set up a simple apache or nginx server to front the JVM through a proxy, then run jetty under it's own UID. Then you can take advantage of the setuid SSL security that is already well-tested in either of those servers. We also have some other requirements that this also helps solve, but I would probably choose to do it this way even if we didn't.
The nginx config is also pretty darn simple:
server {
listen 192.168.1.1:443;
server_name www.mydomain.com;
index index.html index.htm;
root /usr/share/nginx/html;
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/server.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/server.key;
access_log /var/log/nginx/ssl.access.log main;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /AppPath {
proxy_pass http://jettyhost:8080/AppPath;
}
}
I would suspect that, because of the multi-platform nature of Java, there hasn't been much emphasis on Unix-based techniques like what exists in Apache Httpd, since these may not necessarily be applicable to all platforms on which Java can run.
In Java, privilege separation is in-built, by the means of the security manager. Whether this is as good as the root/non-root separation, I'm not sure (there can always be bugs). However, its policies are, in principle, capable of expressing more subtle access rules than just the distinction between a root and non-root users.
Jetty had this, but this was apparently dropped in Jetty 9 (you can still use a security manager, but you may have to write your own policies and do a bit more of the work to implement them in the container).
The Jetty Policy document also states:
Normally a user trusts the application they are developing or are trusting enough to deploy a webapp into an instance of jetty. If you don't know that you need to use the security manager setup, you probably don't.
I'm not sure I'd agree with that. Indeed, if there's a webapp I suspect to be malicious, I won't run it anyway, but using a security manager is also about containing potential security bugs. Anyone can write bugs, even good programmers. Having a mechanism that restrict possible actions by webapps is certainly a good thing.
A sensible policy would certainly prevent webapps from accessing the config files and the keystores.
I would also argue that this webapp separation is also at the core of the notion of "container" (although security is only one of the purposes of this separation, it seems to have been lost).
In fairness, it's not as straightforward as the separation offered by the root/forking mechanism in Apache Httpd. The power of Java security policies also brings complexity. I suppose these features are generally not well understood, and thus little used. Using Apache Httpd (or Nginx, or others) as a reverse proxy tends to be a simpler solution for the purpose of protecting the private keys.
Another way you could look into is using a PKCS#11 keystore. This is supported by the JRE. Hardware Security Modules would help prevent your private keys to be copied. (From a Java point of view, you get a PrivateKey instance that delegates the cryptographic operations to the PKCS#11 library, but from which you cannot extract the private data at all.)
Of course, this is a problem when you don't have access to the hardware, but there are software implementations of this (looking up "Software HSM" might seem odd, but it will bring a few results). Not all of them will let you have the separation you're after, but some should (effectively, by communicating with another entity holding the private key, which you could potentially run as another user). I haven't tried it, but this one might be of interest.
Although I appreciate both #Joakim and #Tony's answers, I was hoping for a more generic solution that covered general password protection without JNI/Jetty specific features and more generic than just SSL secret key protection.
The best solution I can come up with is a small C wrapper program that was setuid root. It would:
Starts up and read in a collection of secret information from root protected files on disk into memory. It should immediately encrypt the secret information in memory (see below).
Switches from root to the unprivileged user running the application.
Forks and exec's JVM with the appropriate application arguments.
Writes the encryption key and the encrypted passwords in via STDIN.
When the JVM boots, it immediately reads in the encrypted secret information from STDIN.
One they are read the wrapper application will terminate.
As an extension, the small C wrapper could stay running and provide access to the JVM to system resources by using a simple line based protocol over STDIN/STDOUT. This would give the JVM access to other protected resources on the system in a controlled manner.
Here are some other thoughts on possible solutions.
A service started at boot time by init.d script that runs as root and serves a collection of secret keys to the JVMs starting up by some web service or though some FIFO file or something. After the first request it would shutdown or after some number of seconds after boot.
LDAP is certainly better than having the secret foo on the box itself -- readable by the application user. As an alteration to the solution above, the setuid program could inject the LDAP password into application so it would not live in user readable space.
As always, both applications would need to protect the passwords in memory. Storing them in system sockets or splitting them up into noncontiguous memory blocks is always a good idea. You could also generate a secret key and encrypt them in memory as well.

How would I go about connecting to a database securely via Java?

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.

Securing the web service in app

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.

Java API - Cloud Service

I hope many people already know about the Dropbox Cloud Service for storing and syncing files across various clients. I am little hesitant using a third party service to store my personal files.
I am trying to build a personal cloud storage using my 2TB Hard Drive. I guess I am looking for pointers on where to start, which APIs to use [preferably JAVA and J2EE], security, risks?
First, I would highly recommend getting over your paranoia; chances are extremely slim that Dropbox employees are going to spend their lunch hour looking at your photos or whatever. Literally millions of people store their stuff on Dropbox and nobody's had their privacy violated.
That said, Dropbox is based on Amazon S3, which (since I assume you trust Amazon just as much as you trust Dropbox) has an open source clone that you can run yourself. Take a look at Eucalyptus. Since you specifically brought up Java, I'll point out that the excellent AWS SDK for Java works just as well on Eucalyptus' S3 stores as on Amazon's.
How is it Cloud storage if it's on your 2TB hard drive? Why do you think your own service will be more secure when accessible through the internet then a service run by people who specialized in doing it. I guess Amazon has probably more experience than anybody else in terms of HTTP accessible file storage (S3).
If you want to make sure nobody can look at your stuff I suggest you look into encrypting it before saving it into S3. That would make it harder to access on the client side, because you always need the right tools to do the encryption stuff but that is the price you'd have to pay.

Categories

Resources