I want to hide arguments (password paraphrase) from a running java process (can be seen from command line).
For example, when i type jps -m on cmd, it shows me all the java processes along with their arguments:
Output after running jps -m: 6120 someproject.jar -password
where 6210 is pid.
I need that password to run java process. The problem is if my machine is compromised, someone could read password and can do further damage.
One solution could be storing password in a file locally. But still someone can get it if machine is compromised.
Any ideas how i proceed ?
Thanks in advance.
update1: The password is hashed but still i want it to hide.
The way you would handle this in (for example) a C program would be to write over the argument list supplied to the main(...) entry point method. For more information read this:
https://unix.stackexchange.com/questions/8223/can-other-users-view-the-arguments-passed-to-a-command
Unfortunately, the "overwrite" approach is not available to a Java application. From pure Java, it is simply not possible. Even with native code library, it would be difficult to find where in memory the (native) argument vector is stored.
(And besides, there is a small time window in which the arguments are exposed ... before the application erases them.)
So your best bet is to pass the secret information another way. For example, pass the secret info via an environment variable, via a temporary file with access restrictions, or via standard input.
Related
From what I read, there are a couple of ways to run java files in a node.js application. One way is to spawn a child process: (the java code is packaged with dependencies in an executable jar.)
var exec = require('child_process').exec, child;
child = exec('java -jar file.jar arg1 arg2',
function (error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
});
The other way is to use the java - npm module (link), a wrapper over JNI (this will let me create objects, set and get attributes, run methods).
In a production environment, when I want my node.js (Express) server to call a java program (it just saves an image to the local directory), please advise me on which would be the better way to accomplish this (in terms of best practices). Also, there is a long list of arguments that I need to pass to the main class and doing that on the command line is a bit of a struggle. Should I make the java program read from an input file instead?
1) If you use exec, you will run an entire program, whereas if you use a JNI interface, you'll be able to directly interact with the libraries and classes in the jar and do things like call a single function or create an instance of a class. However, if you don't need anything like that, I think using exec is far simpler and will also run faster. Sounds like you just want to run the Java application as a standalone process, and just log whether the application finished successfully or with errors. I'd say it's probably better to just use exec for that. Executing a child process this way is also far better for debugging, debugging JNI errors can be very difficult sometimes.
2) As for whether or not to read arguments from a file, yes, it's usually better to read from some sort of file as opposed to passing in arguments directly. It's less prone to human error (ie. typing in arguments every time), and far more configurable. If someone like a QA engineer only needs to edit a config file to swap out options, they don't need to understand your entire codebase to test it. Personally I use config files for every Java program I write.
You can use deployment toolkit and run the jar through jnlp. https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_toolkit.html
Advantage of running jars through jnlp is the ability to pass parameters from javascript to your jar. In this way you can dynamically customize your java program.
For this kind of problem you'd want to approach it in the following way:
Is there a decent way to run processes with arguments in my language/framework
Is there a decent way to deal with the programs output?
From experience, a decent way to deal with arguments in a process is to pass them as an (string) array. This is advantageous in that you do not have to resort to unnecessary string interpolation and manipulation. It is also more readable too which is a plus in this problem setting.
A decent way to deal with output is to use a listener/event based model. This way, you respond appropriately to the events instead of having if blocks for stderr and stdout. Again, this makes things readable and let's you handle output in a more maintainable manner.
If you go a bit further into this, you will also have to solve a problem of how to inject environment variables into your target program. As an example, you might want to run the java with a debugger or with less memory in the future, so your solution would also need to cater for this.
This is just one way of solving this kind of problem. If node is your platform, then have a look at Child Process which supports all of these techniques.
We can run the whole java project by making .jar file of it and run it using the command in the shell and run that shell file. In order to run java code from nodejs project as we know project could be a mix of java, js modules.
Call exec() function in node to create a child process to execute the shell file having a command to run .sh file and can also pass some argument in it from use.eg;
let fileName = 'someFile.txt';
let userName = 'Charlie Angle';
exec(`sh run.sh --context_param
paramFilePath="./storage/${fileName}" --context_param userName="${userName}"`, (error, stdout, stderr) => {// Some code based on execution of above command})
You can simply call a java command , with classpath & arguments, using module node-java-caller, it embeds the call to spawn and will also automatically install java if not present on the system
https://github.com/nvuillam/node-java-caller
My Java application has to work like this:
User select bash commands in GUI and press "send."
Application return distinct and independent answers for each command (e.g. we could store them in different files).
Commands each run interactively, not in a batch (it can't be something like "ls\n pwd \n" etc)
After each command, the application will check if the results are ok. If so, it will send the next command.
We need to execute su <user> on the remote host.
This will be a plugin for a bigger app, so answers like "try something else" (i.e. RPC, web services) will not help me :(
As far as i understand i have to use SHELL or at least keep channel connected.
I have tested jsch , sshj and ethz.ssh2 but with bad results.
I've dug throu stackoverflow answers for questions like: "sending-commands-to-server-via-jsch-shell-channel" etc. But they all focus on sending whole commands in one line. I need an interactive, persistent SSH session.
I've used ExpectJ (with a little hack of output stream). It has resolved points 1,3,4,5.
But there is a problem with point 2. In my app I need to get separated answer. But we will not know their length. Command prompts can be different. Anyone knows how to "hack" ExpectJ so it will be some how more synchronized? I am looking for acting like this : send , wait for full answer, send, wait... I've tried some basic synchronization tricks but this end in timeouts and connection lost usually.
You should use ExpectJ, a Java implementation of the Unix expect utility.
not sure if you still have the problems,
in any case, it might contribute to other people.
ExpectJ is indeed the Java implementation of Unix expect.
and you should definitely buy the "explore expect book" then look into it, it is worth it.
For your question:
when you spawn a process, you listen to the return output, match it to a prompt, then send some command.
if you want to analyze the output, you buffer that output, and do some actions before the next send()
to do so, you need to use the interact() method of the spawn class you used.
http://expectj.sourceforge.net/apidocs/index.html
and for interact and how it works:
http://oreilly.com/catalog/expect/chapter/ch03.html
look for this part: "The interact Command"
In Java, you can execute a process and pass command line arguments to it via Runtime.getRuntime().exec().
The arguments you passed into the program can be seen in the task manager or the process explorer. I want to know if there is a way to hide or clear that command history, so that it can be seen by neither.
Any help is appreciated.
You cannot hide the process or the full command that started it. Whatever you pass as command to Runtime#exec will show and there is no way around it.
Your alternatives are:
Integrate the functionality into your application instead of starting a new process. If it's your own native code, you can use JNI to run it. If not your code, you can look for a Java library that does what it does. This is what I would recommend.
Pass the arguments via IPC (stdin/out, tcp, etc..).
Read the arguments from a temporary configuration file that will be deleted once the process starts.
My Java application has to work like this:
User select bash commands in GUI and press "send."
Application return distinct and independent answers for each command (e.g. we could store them in different files).
Commands each run interactively, not in a batch (it can't be something like "ls\n pwd \n" etc)
After each command, the application will check if the results are ok. If so, it will send the next command.
We need to execute su <user> on the remote host.
This will be a plugin for a bigger app, so answers like "try something else" (i.e. RPC, web services) will not help me :(
As far as i understand i have to use SHELL or at least keep channel connected.
I have tested jsch , sshj and ethz.ssh2 but with bad results.
I've dug throu stackoverflow answers for questions like: "sending-commands-to-server-via-jsch-shell-channel" etc. But they all focus on sending whole commands in one line. I need an interactive, persistent SSH session.
I've used ExpectJ (with a little hack of output stream). It has resolved points 1,3,4,5.
But there is a problem with point 2. In my app I need to get separated answer. But we will not know their length. Command prompts can be different. Anyone knows how to "hack" ExpectJ so it will be some how more synchronized? I am looking for acting like this : send , wait for full answer, send, wait... I've tried some basic synchronization tricks but this end in timeouts and connection lost usually.
You should use ExpectJ, a Java implementation of the Unix expect utility.
not sure if you still have the problems,
in any case, it might contribute to other people.
ExpectJ is indeed the Java implementation of Unix expect.
and you should definitely buy the "explore expect book" then look into it, it is worth it.
For your question:
when you spawn a process, you listen to the return output, match it to a prompt, then send some command.
if you want to analyze the output, you buffer that output, and do some actions before the next send()
to do so, you need to use the interact() method of the spawn class you used.
http://expectj.sourceforge.net/apidocs/index.html
and for interact and how it works:
http://oreilly.com/catalog/expect/chapter/ch03.html
look for this part: "The interact Command"
I have a web application that runs as a user www. However at one point it needs to read a file from a Linux filesystem on behalf of users Alice and Bob.
One way of doing this would be to launch a shell (Runtime.exec()) and call a C setuid executable to change userid and read the file.
Is there a way to achieve this with JNI (the web app needs to run as www and not root)? I tried to write a Java JNI program that calls native methods on Linux (I made these native methods owned by root and have setuid bits set). But unless I run the Java program as root, it does not let me switch user ids. Is there something that I am missing? Is there a way to achieve this?
Thanks!
No. There is not. setuid and setgid can only be used in two cases (on ordinary Linux):
The process is root.
The process was launched from a file with the setuid or setgid bits in its modes.
In the former case, the process may call these functions willy-nilly to adopt any identity. In the later case, the process my only switch back and forth between the uid/gid of the parent and the uid/gid of the file it was launched from.
That is, if setuid, it may adopt the uid of the file, if setgid, the gid.
Since you are in java, the exec-ed program is java itself, and you don't want that to be setuid or setgid, not unless you want to create a colossal security exposure.
You could write a C or C++ program that started the JVM via the JNI invocation interface, and set that program to be setuid or setgid, and then JNI code invoked in there could make the appropriate calls to switch.
Yep, it's possible. You can see an example here:
https://github.com/kebernet/pretty/blob/master/src/main/java/com/reachcall/util/SetUID.java
Here's example of the code:
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
public static int setuid(int uid) {
if (Platform.isWindows()) {
return OK;
}
return CLibrary.INSTANCE.setuid(uid);
}
bmargulies's answer is not correct (or not quite correct).
A non-root process in UNIX can set uid or gid, if it has respective capabilities:
http://man7.org/linux/man-pages/man7/capabilities.7.html
CAP_SETUID
Make arbitrary manipulations of process UIDs (setuid(2),
setreuid(2), setresuid(2), setfsuid(2));
Since from OS prospective, your program is running as "java" process, this setguid capability must be enabled for the java executable itself:
$ sudo setcap cap_setuid,cap_setgid+ep /usr/java/latest/bin/java
Also notice that filesystem where java executable resides, isn't mounted with "nosuid" option.
Back to your original question
the web app needs to run as www and not root
Normally it's not a good idea to let web service to have a setuid capability.
It's better to drop uid in a shell wrapper script that starts up your web application.