views:

213

answers:

4

Hi Everyone,

This may seem like a very broad question, but any help is appreciated.

I have a client/server solution written in java which uses the Cajo project (which uses RMI). I just want to try and make my solution as secure as possible, given the sensitive data that will be transferred between server and client.

So far, my ideas are to make all my classes "final" as well as throw a "non-serializable" exception for all my classes in the server (except for the object bound in the RMI registry, and any objects that actually do need to be transferred of course).

Can anyone think of any other ideas?

I know that someone could write a malicious client - this isn't hard to do as you can find out the remote object's API using reflection. However is there anything I can do to protect a malicious client access classes/objects within the server that they are not supposed to access?

Many Thanks

Update: Thanks everyone for the helpful tips, and sorry it took so long to get back to yous. My current train of thought is this for make a secure system:

  • Use OpenVPN between the clients and the server. This means that you need access to the physical client to gain access. (N.B. Due to the 2 points below, the VPN will actually be between the server and the office LAN. I feel that this is secure enough)
  • Use usernames and password (maybe using JBOSS) for authentication between server and client. This means that for anything to get done on the server, an attacker would need the username and password.
  • Throw a "Non-serizable" exception for all objects, except the ones that are actually supposed to be sent over the network. This stops sensitive objects from being sent over the network.

Does that sound fair? Please correct me if I'm missing anything.

Further Update: It appears there seems to be some confusion over what I'm trying to prevent against. What I'm trying to prevent, is someone from "hacking" the server. So basically exploiting the server to dump/drop its entire database, for example.

Thanks

A: 

I would use a custom socket factory to encrypt all the RMI data. E.g. Using SSL will prevent viewing the data, modifying it, and replay attacks.

This tutorial describes how to create a custom RMI socket factory, and a general discussion of RMI over SSL.

It might seem like a lot of work, but if you really must hide sensitive data from anauthorized eyes, then making objects final will simply not provide any real security - the sensitive data can still be read.

EDIT: This is all pretty much a moot point, since the OP mentioned in comments below that a VPN is being used.

mdma
-1 for suggesting something extremely insecure...
Longpoke
Thanks for the reply. I forgot to mention in my post above that I will be using a VPN to encrypt all data between client and server. Do you think a VPN is enough, or should I go a step further and do what you've suggested above?My main line of thinking is this: the client end is insecure. The PCs probably won't be properly protected (I'm not incharge of the day-to-day oversight over them). So since the server end will be locked away in a secure data centre, it is the server that I want to protect the most
jtnire
That depends upon your VPN. Sorry, that's outside of my field. @Longpoke - can you explain?
mdma
When the prize of deobfuscation is remote compromise, the obfuscation will certainly be defeated. And the PKI should be setup such that compromising one machine doesn't let you sniff traffic from others. If this is a mesh network, every peer needs its own key. Otherwise you can just make the server have its own key and optionally give clients keys as well.
Longpoke
I see, but how is it less secure than not using client side certificates at all? When the client certificates are discovered it renders client authentication worthless, but not insecure, i.e. no less secure than not using client side certificates? I see the only danger is the implied security you may think you are getting with authentication.
mdma
It shouldn't be possible to get the private keys from the other peers, no peer should be able to compromise another through RMI. I don't see where obfuscation comes into play here.
Longpoke
To be on the safe side, I've removed the part discussing client side certificates.
mdma
I was under the impression that SSL still incorporated a random component in the encryption even when using a client cert so even a holder of the client certificate could not immediately decipher an intercepted stream.
mdma
Well, SSL negotiates a shared session key independently of the certificates, and a leak of the client's private key and certificate won't compromise that, but it compromises authentication and authorization of that client: i.e. it permits anyone with the leaked material to connect as that identity - no snooping required. SSL is not secure without reliable authentication. See RFC 2246.
EJP
@EJP, thanks for the confirmation. That's what I thought. In essense, a comprimise makes the client authentication worthless, but not insecure. I.e. the fact that a client has authenticated is not to be trusted any more than an unauthenticated client. My point to including it originally was as one extra layer of difficulty that an attacker would have to circumvent, and not as a way to securely authenticate each client. (I did mention each client would use the same cert, so I hoped it was understood that this was not trusted authentication.)
mdma
Hmm? 1. Setup an internal CA, 2. give each Cajo node a cert signed by the CA. There _is_ no compromise, why do you think the Cajo servers are any more vulnerable than Google Internet Authority, Verisign, etc?
Longpoke
A: 

Does Cajo only let you invoke methods on exported objects? If so, simply only export safe-to-be-invoked-remotely objects. Otherwise you are forced to use the sandbox if you want the hosts to be secure. Also see this.

You will need SSL to prevent sniffing/modification of network traffic.

Longpoke
A: 

You mention that you are using VPN, so for a malicious client to connect to your server, they would have to comprimise your VPN, or install rogue software on a machine with legitimate access to your VPN.

Once this is done, then there is no easy way to distinguish a rogue client from your authorized software. You could proide additional credentials to each user of your client software for additional authentication, but these can be comprimised if the client machine is comprimised. A stronger authentication scheme is to send each user a small "widget" that computes access codes. An rogue client will not have access to this, and it cannot be comprimised by software alone since it is physically separate from the client machine. Combining this with a username/password for each user will defeat one user stealing another user's widget.

Depending upon how secure you want it and how much effort you are prepared to invest, this may be overkill. If your primary concern is guarding against an automated attack from a rogue client vs a regular user using the software, you could implement "I'm a human" authentication by presenting a capcha at login.

mdma
I'm pretty sure he wants to _secure_ his RMI architecture, ie: make it so if he has 500 nodes, and one node gets compromised, it can't use RMI to compromise the others, because they don't export dangerous objects. Other than that, SSL, TLS, SSH, Keberos, IPSec, etc are all good enough by default. VPN is only good if it provides auth/confidentiality.
Longpoke
What I'm trying to prevent, is someone from "hacking" the server. So basically exploiting the server to dump its entired database, for example.
jtnire
A: 

Protecting a system that connects with potentially compromised systems over RMI is very difficult. The first thing to do is to disable the dynamic code loading feature of RMI using the java.rmi.server.useCodebaseOnly system property - no more mobile code (via this channel).

Tom Hawtin - tackline