Storing Service Account Username and Password - java

I am building a java web application that will automatically grant users Administrative Rights to their Windows PC's when a manager approves their request.
In order to accomplish this, I am going to write a script to automatically remote into the users computer and add them to the computer's administrative group. I figured in order to do this though, I will need to have an Administrative Service Account to access all computers.
My question would be, how can I go about securely storing the Administrative Service Account information? The application will need the credentials every time it needs to go and give a user admin-rights, so how can I go about letting the application use the Service Account without human interaction? Obviously I cant just put admin credentials in a plain-text properties file. The credentials shouldn't be open for any developers to see who might go in and change the application later.
Could there be a better way to do this? Someone mentioned to me once maybe having an account in Active Directory to impersonate, but I wasn't able to follow up for more details on that.

There is one method of protecting service account passwords that is occasionally used for services that use databases is based on the concept of inversion of control.
Here the service can call a stored procedure, which has anonymous access, that prompts the database to generate, set, and send the password to the service, whose address it knows, via a separate call.
While the anon call is normally IP limited to prevent DoS attacks, it doesn't matter if some other process calls it, because the stored procedure will only send the password to the service regardless of who calls it.

Related

How to secure an SFTP password in an APK file

I'm developing an Android app which has a service to upload images/files to a FTP server.
To make that possible, the app on the device has to log in into the FTP server before sending data.
And here comes my problem. The user does not need to / have to know about the FTP login data. Only the app itself. I have to store the login data in the Java class. But how should I secure the user and password?
I could encrypt it or obfuscate it. But I think it would be possible for a hacker to read the password at the runtime when the "setPassword(passwordString) methods is called by the JVM:
String passwordString = "myPass";
JSch ssh = new JSch();
session = ssh.getSession(SFTP_USER, HOST_ADDRESS, 22);
session.setPassword(passwordString);
So how could I store my credentials inside the APK file and secure them? I don't want anyone to get access to my FTP server.
how could I store my credentials inside the APK file and secure them? I don't want anyone to get access to my FTP server.
The stated problem cannot be solved.
It does not matter how clever your obfuscation technique is. If you hide fixed credentials in the APK file then someone who analyses your app is going to find them.
If you take only one thing from this answer, let it be that having a single, static password for your server is extremely problematic, as you'll never be able to change the password server-side, because you'd break all the apps. It will be a matter of time before your password is public knowledge and there will be nothing you can do about it.
Any reasonable approach requires separate access credentials for every individual user.
A traditional user sign-up system that involves a confirmation email is a pretty good approach. You can use something like Google+ sign-in or Facebook Connect to minimize the hassle for the end user.
If you absolutely insist on having zero user interaction, an approach that might work (somewhat) is to have the app register for Google Cloud Messaging and then send it a push notification containing access credentials, which the app will store in the KeyChain.
If you generate a unique user ID and password for every app installation, you'll be able to monitor the server and block any abusive access credentials without affecting any of the other users. If you somehow factor the code signing identity of the APK file into the process, you'll have a basic defense against people repackaging your app. This approach will not protect you against an intelligent attacker, but it might raise the bar high enough for your purposes.
Also, regardless what you do, be sure to properly verify your server's SSL certificate. If you don't, an attacker will simply run your connection through a proxy server.

How to get windows user name in java

I write a web application I have to do signin in that using the windows username..
I tried to get username using system.get property() but its giving the username of server windows name only.but I want to the username of client system..can any one help me?
If I understood you correctly you want to sign in to the web application using the Windows credentials. If so - the problem is that the server machine knows nothing about the client. It can provide you the user info only after successful login (see Get windows username using JAVA or JSP).
You could point your system to some user store (e.g. LDAP) that will be used by both Windows system and your app. In this situation you will be able to sign in to the app using Windows credentials.
The Browser is an application to generate the view based on an HTML code. It wont give access to the client machine.
You can use request.getRemoteUser() to get the user name, that too is possible only if its allowed in the client machine.
If your client is running on a windows machine you can get the user name using this
var wshshell=new ActiveXObject("wscript.shell");
var username=wshshell.ExpandEnvironmentStrings("%username%");
This is a solution for getting the user name, but i will never recommend this, it surely is a bad practice.
Is the entire Java application running on the server? How would your application even know about a specific client machine? And how would it deal with concurrently logged in users? And how would it deal with a primitive client machine which does not have a notion of a user name?
You can instead run a Java applet which is invoked on the client's machine. You could the send this information to the server to process. However, your users would most likely not like that and not grant the required privileges.
Alternatively, you could try to use JavaScript to read the user name, in case that you are communicating via a webpage. I want to stress the word try in this context since there is not universally functional approach and most users will most likely not allow you to read this property either.
In a nutshell: Users do not normally want to share this information with you and therefore you cannot access it. If you could, you would have found a security hole which would most likely get fixed. Rather, ask your application's users to enter a name to use for whatever reason you would require it. Or, if this is an option, organize for example your Windows credentials in a service that can be accessed by a standardized API.

Hide private keys etc from administrators

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.

Java and system user authentication

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.

Java EE security - application clients

I'm writing on a Java EE project which will have everything from 3-6 different clients. The project is open source, and I wonder what security mechanisms one could/should use. The problem is: Because it is open source, I would believe that it is possible for anyone with a user to write their own client (maybe not realistic, but truly possible) and make contact with the server/database. I've tried to go through all the scenarios of reading/writing different data to the database as different roles, and I conclude with that I have to have some security mechanism on a higher level than that (it is not enough to check if that account type is allowed to persist that entity with that ID and so on...). In some way I have to know that the client making contact is the correct client I wrote. Could signing the Jar files solve this entire problem, or is there other ways to do it?
-Yngve
I really think that if restricting the available activities on the server side (based on role) is not sufficient, than you've got a bigger problem. Even if a user doesn't write their own client, whatever mechanism you are using for your remote calls is likely to be vulnerable to being intercepted and manipulated. The bottom line is that you should limit the possible calls that can be made against the server, and should treat each call to the server as potentially malicious.
Can you think of an example scenario in which there's a server action that a particular authenticated user would be allowed to take that would be fine if they're using your client but dangerous if they're not using your client? If so I'd argue that you're relying too strongly on your client.
However, rather than just criticize I'd like to try to also offer some actual answers to your question as well. I don't think signing your jar file will be sufficient if you're imagining a malicious user; in general, public-key cryptography may not help you much since the hypothetical malicious user who is reverse-engineering your source will have access to your public key and so can spoof whatever authentication you build in.
Ultimately there has to be someone in the system you trust, and so you have to figure out who that is and base your security around them. For example, let's imagine that there may be many users at a particular company who you don't necessarily trust, and one admin who oversees them, who you do trust. In that scenario you could set up your client so that the admin has to enter a special code at startup, and have that code be kept in memory and passed along with any request. This way, even if the user reverse-engineers your code they won't have the admin code. Of course, the calls from your client to your server will still be vulnerable to being intercepted and manipulated (not to mention that this requirement would be a royal pain in the neck to your users).
Bottom line: if your user's machine is calling your server, than your user is calling your server. Don't trust your user. Limit what they can do, no matter what client they're using.
Well the source may be available for anyone, but the configuration of the deployment and the database certainly isn't. When you deploy the application you can add users with roles. The easiest thing to do is to persist them in a database. Of course the contents of the table will only be accessible to the database administrator. The database administrator will configure the application so that it can access the required tables. When a user tries to log in, he/she must supply a username and password. The application will read the table to authenticate/authorize the user.
This type of security is the most common one. To be really secure you must pass the credentials over a secure path (HTTPS). For a greater degree of security you can use HTTPS client authentication. You do this by generating a public key for every client and signing this with the private key of the server. Then the client needs to send this signed key with every request.
EDIT: A user being able to write his/her own client doesn't make the application less secure. He/she will still not be able to access the application, if it is required to log in first. If the log in is successful, then a session (cookie) will be created and it would be passed with every request. Have a look at Spring security. It does have a rather steep learning curve, but if you do it once, then you can add security in any application at a number of minutes.

Categories