My company has a Java Web Application with the database password stored in a properties file and we need to secure the password. I've googled and found the Jasypt solution, but in my mind that doesn't really solve the problem because that requires another password to feed to the application and I don't know how to secure that password.
The main suggestion for Jasypt is to feed the password in as an environment variable, which means that in the best case scenario I would be starting the application like:
./myApp -D password=myPasswordDontHackPlz
which isn't secure because you can see the password when you do
ps -ef | grep myApp
We also can't feed the password in when it needs it (via a the web or something) because it essentially decides when it needs the password, and it needs it pretty often.
Is there any solution to this or am I asking for some magical solution that doesn't exist? I don't like Jasypt because it seems to me to essentially just be obfuscation, and I'm not after obfuscation i'm looking for true security here.
Why don't you put the password in a properties file which is only readable by the user that runs the web application? The web application will need to know the root password at some stage, so obviously you want it to be able to read/use it. What you want is that noone else should be able to read it, and protecting the file will do it.
This is all assuming that you need to externalize your password. You could hardcode it into the application if you wanted to make it harder to get at, but someone with access to the JAR can always decompile your classes.
I am just wondering - storing a root database password is a bad idea in general. But then again, when someone actually manages to get access to that file on the server, how safe is your database anyway?
Would the password still show up if you created a shell script and run it instead?
#!/bin/bash
./myApp -D password=myPasswordDontHackPlz
Related
This is a follow up to:
Using JSch to SFTP when one must also switch user
This issue has been on the back burner since I asked the original question while our server management team reviews their policies, but I am now picking it up again!
What I want to do is to use JSch to connect to a remote server and then use sftp or scp to access some files - as per the code example in the original question. The issue is that these files are owned by another user and so I need to su to that user and then provide a password before issuing the sftp or scp command.
This cannot be done in JSch and this is right because it is a security risk to be able to send the password through the exec channel. So these are options I have going forward as I see them.
Override JSch functionality. Martin has very helpfully provided some guidance in an answer to the original question as to how this could be done by and how the password may be passed in "through the back door". But I am not confident in my own ability to override the JSch code and once again, even if successful, I would be circumventing a security feature that is there for legitimate reasons, so I am reluctant to attempt this.
On the server, grant my user password-less access to the other user. This is a no as my server management team will not agree to this.
Have a server-side .sh script that can be run by my user to gain access to the files. Again, this is a no as my server management team will not agree to it!
Automate a putty session i.e. phsically open putty and pass commands to the putty session line by line from the Java client.
Give up! Should I accept that I am trying to do something here that should not be automated and simply have a manual test instead?
I would be extremely grateful for any thoughts/guidance.
I am trying to do something here that should not be automated.
That's correct in principle.
The only correct automatic solution is to directly login with the user that has access to the files. Everything else is just a hack or working around your security policy. Ideally you should authenticate with a dedicated private key to allow monitoring the access from your application and to be able to control the access (e.g. temporary turning it off, without affecting other uses of the same account).
Though I can imagine that your system administrators won't allow you the direct login, because they cannot foresee what (if any) security issues it brings.
I just wanted to share that I have got a solution working for this question by adapting the sample JSch example, JumpHosts.
http://www.jcraft.com/jsch/examples/JumpHosts.java
Overriding the inherited methods in the static class MyUserInfo allowed me to automatically accept prompt boxes, input boxes, etc without physically having to use the keyboard, so I have a fully automated test as desired.
It's great that the jcraft team provide such useful worked examples. Thanks for everyone who took the time to read and consider my question.
Edit: As per Martin's comment, I should point out that this only works if you have a special rule in SSH configuration that allows direct user2 login from localhost (while not allowing direct remote login). That's not sudo. So this cannot work in general.
I need to develop a web application for the Intranet users. I don't want them to enter the login credentials each time they visit the site. It should be automatically loaded from the System Username and Password.
I have successfully implemented functionality which prompt user name and password registered with active directory and validate against LDAP. I need some tips to login directly from intranet website without prompt username & password.
Here is my queries, please let me know your suggestion.
Is it compulsory to set SPN?
Do we need to create separate keytab file for each client? In my organization, there is around 800 people are working so should I need to add all client principal in keytab file & copy to client machine to perform autologin.
I have tried many API's like JESSO, Waffle, Spring Kerberos, SPNGO but failed to implement auto login.
If you want to use Kerberos/SPNEGO (which would be my recommendation) you do have to set up SPN. And you only need one keytab for AD domain. Are you running your Java program on some app server, like Weblogic, or as a standalone program? Servers do have security framework that you could use, while for standalone program you'd have to do a bunch of stuff manually.
I've found that the easiest way to do this is to use Atlassian's Crowd (https://www.atlassian.com/software/crowd/overview) instead of implementing it yourself. It's a commercial product, but last time I checked, it was dirt cheap, and it just works.
Currently I take part in developing a system based on Java EE (WebLogic server, to be more precise) and I am wondering how to protect some private data from administrators. For example, some parts of a system stores credentials for legacy systems in a deployment descriptors as plain text and this is bad because a deployer can read application configuration file (ejb-jar.xml, for example) and steal username and password for powerfull account. I want to close this security hole, but don't know how.
Now I am interested in protecting this kind of data:
Login
Password
Private key for symmetric encryption
From here I've discovered that I can use a JCEKS keystore to protect this type of information, but I can not understand how to use it. My application still should contain the kestore password and the key password to access it. So, a depoyer can steal passwords for keystores and keys, find my secure storage and steal credetials. Obviously, I can revoke read privileges from the deployer account, but then he can decompile my appliaction and develop his own similar app (or edit my one), that simply prints secure data to some file or send it by email... And now I am stuck...
Can anybody give me some links that can explain how to protect a system from administrators? Weblogic related links will be preferable. I totally understand that it is not possible to protect from all administrators and there should be some security administrator that will be responsible for keystore management and so forth, but I want to secure all sensitive data from everybody else.
RESULTS
Both jtahlborn's and slim's answers are correct, but slims's answer in more interesting. I think that in my case it will be appropriate to accept only signed applications for installation on the server. This decidion can solve problem with applicatoin modifications done by a administrator. Administrators will have password from keystore and all keys, but they will not have access to keystore file at all. Access to keystore file will have only special security administrators ('rw') and server ('r'). So, everybody will have the key, but nobody (except security administrators) will have access to the box.
There is no solution to this problem unless you enter login credentials at application startup (assuming the admin cannot access the application memory, which may not be a safe assumption). any solution which involves the keys sitting in the same place as the application will result in an administrator (with application filesystem access) being able to access any sensitive data accessible by the application. this is similar to the DRM problem (you can't give someone a locked box and the keys and expect that they can't open the box).
I think the meat of this question is in the definition of "admin".
You've said that you're comfortable with a "security admin" who does have access to key stores.
Traditionally, UNIX types think of "admin" as being the "root" user - someone with access to everything on the machine. Root can do literally anything, right down to peeking and poking at application memory, or reading/writing to raw disk addresses. If the server can get a private key, so can root.
If you want to define an "admin" role with more limited access, then yes, you could set up something where such users existed. They would need to have fewer privileges than the server application itself, since there is at least one thing the app can do (get a private key) that the "admin" cannot.
Such a user probably wouldn't be able to install the app either (since, if they could, they could create and install a version of the app which exposes the private key). Your "admin" couldn't therefore deploy the component that works with the private key. They could, however, potentially deploy a module that runs within that container (as long as the container cannot supply the private key to the module).
However, it's not just the key you want to protect. The real "secret" is the data encrypted using the key. So we still have a problem with the approach above. If the module can read the encrypted data, then so can an "admin" with the same privileges as the module. And that includes anyone who can install the module.
You could investigate ways to sign the module, so that an "admin" could not create their own version.
There comes a point, though, where the measures required to enable untrustworthy admins, become more expensive (in terms of time and effort) than simply using trustworthy admins.
So, you need to make a list of things your so called "admin" can do. Depending on what those things are, it may well be possible to allow a non-root user to do those things. On UNIX, you might use a tool like sudo to allow a non-root user to do things like start/stop the server, read logs, clean logs, etc.
It might be possible to separate the authentication from the rest of the application.
For example, if you communicate with the legacy systems via a TLS-secured socket, you could write a small separate application that accepts unencrypted connections from the application, then makes a secure, authenticated, connection to the legacy system, and pumps data between the application and the legacy system. Essentially, it's an authenticating proxy. Then, the application wouldn't need these keys. You could install and operate the application as a user who didn't have permission to read the files containing the key, but the application could still communicate with the legacy systems.
Of course, now you have the problem of how to authenticate the application to the proxy. You might feel that the machine is secure enough that you don't need to do that at all - as long as the proxy only listens on the loopback interface. If not, if you could use a unix domain socket instead, then you could control access using filesystem permissions: you could run the application as some user in some particular group, then restrict access to the socket to members of that group. Java doesn't have unix domain socket support in the standard library, but you can add it with junixsocket or JUDS.
I'm in the process of writing a server application that mainly allows people to submit jobs to a DRM system (e.g. TORQUE) over RMI. The application needs to run as root so that it can submit proxy jobs (where a job is run as a user other than the user who submits it), however this obviously isn't secure - the user name is simply a string parameter in the RMI. Anyone could pass any user name in and have a job run as that user.
What's the best way to get Java to authenticate this user name against authorised users of the system (with the aid of a password that would also be passed in)? I've had a look at JAAS and Apache Shiro, but they seem to be all about creating your own authentication methods. I want to use the system's existing authentication methods (Unix-like system), whatever they happen to be. Essentially if the user can SSH in, they're all right.
If your backend uses LDAP (which is possible if you have to manage a relatively large number of users for which a local /etc/passwd might be tedious), you can use JAAS and the existing LdapLoginModule.
If you want to authenticate against you local system (assuming Linux server) without this, it looks like JAAS-PAM might be able to help, although I've never tried it.
I have a text file on a unix machine containing the SSH user name and password that someone might use to connect to it.
How do I verify that the user name and password are valid using Java?
Do I try to SSH connect to the same machine by using Runtime.exec()?
I can grep for the user /etc/passwd. But, the password is shadowed.
I'd appreciate any suggestions.
Maybe the question could be broadened to "Validating UNIX Credentials from Java" as the mechanism explained is not really ssh dependant.
Here is my shot as a better Expect-like alternative (e.g. with ProcessBuilder) without using the overhead of a network stack:
su -u username -c echo
Just check the exit status to know the answer.
(Bonus points: su is present on all UNIX operating systems, and it's even probably on the PATH and is valid as well for other external authentication system as LDAP).
If you have root access, then of course you could read /etc/shadow. I would say this is the "correct" way of doing it.
Other than that, your friggly way of calling ssh should be OK I think, but I'd use ssh to run a command that, say, created some random temporary file-- then, if the file was created (or the command carried out), you assume the user name/password was correct. Sounds icky, but you can probably get it to work in an emergency.
Oh, of course, the frig has the side effect that you actually logged in as that user. That may or not be desirable...!
Remember that there is more to UNIX authentication than /etc/passwd and /etc/shadow. They could for instance be authenticating against Kerberos, LDAP, NIS or any other number of sources. For this reason, I would highly recommend looking into a PAM wrapper for Java. A quick google turned up http://jpam.sourceforge.net/ but I have no experience with it.
Of course sshd may be configured not to use PAM at all or to only allow certain users, etc. If you want to follow sshd's rules exactly then that changes things, but it sounds like PAM auth is more what you want.