To get the name of the current user in a Java program, you can simply fetch the value of the user.name system property:
System.getProperty("user.name");
But how secure is that? Can a user executing the program easily set this property to an arbitrary value (using a command-line argument of the JVM, for example) for common runtime environments? Can a user easily spoof this user name?
I ask because I am writing a command-line program that can be run by anyone, but allows some privileged operations only if the user is a special administrative user.
Note that since Java 11 the user.name property is effectively read only once the program starts, so malicious program code can not spoof it.
Yes this value can be 'spoofed' and cannot be relied upon if the user is free to start the application.
Simply starting the app with the JVM arg -Duser.name=someothername will cause System.getProperty("user.name") to return that value.
For anyone possible landing on this ever again:
Using the cmd-command whoami and reading the input using this post should be a more secure way of using the username as "validation".
Except, this can be spoofed as well, which might be harder for a cmd-command than for a JVM argument...
Related
If the input is interactive, i.e. from the console, I want to print a command prompt e.g. ">"
But if it is redirected e.g. from a file, then I do not want to prompt.
System.in is an abstract InputStream which does not appear to have any method for this.
Maybe you could use instanceof if the concrete type is different?
As well, if System.out is redirected to a file I also do not want to prompt
AFAIK, there is no way to do this in pure Java, and even doing it in JNI / JNA would be complicated.
An alternative might be to use the new Console API introduced in JDK 1.6. This allows you to try to get a reader/writer for the console. If it succeeds, the result is guaranteed to be interactive ... in the sense that you mean.
A second alternative would be to do the "check for interactivity" in the wrapper script that you use to launch your application, and pass the information to Java via the system properties. For instance, on a GNU/Linux system the tty(1) command can be used to tell if stdin is a connected to a "tty" device.
Note that there are other ways to deal with a requirement to avoid unwanted prompts when running non-interactively:
If System.out is redirected to a file I also do not want to prompt.
(I think you might mean that System.in is redirected. That is the normal way to non-interactively run an application that normally takes interactive input from the user ...)
The alternatives include:
You could modify the program to write the prompts to (say) System.err and redirect that to a different place.
You could modify the program to have options that mean "don't prompt" or "take input from a file".
Since Java 6 there is the method java.lang.System.console():
Whether a virtual machine has a console is dependent upon the
underlying platform and also upon the manner in which the virtual
machine is invoked. If the virtual machine is started from an
interactive command line without redirecting the standard input and
output streams then its console will exist and will typically be
connected to the keyboard and display from which the virtual machine
was launched. If the virtual machine is started automatically, for
example by a background job scheduler, then it will typically not have
a console.
If this virtual machine has a console then it is represented by a
unique instance of this class which can be obtained by invoking the
java.lang.System.console() method. If no console device is available
then an invocation of that method will return null.
I want to obtain the name of the user who has installed a software, to be written in the installation log. Is it at all possible? Please throw some light.
You could try to use java.lang.Runtime.exec() to call the linux command 'whoami'. that will give you the current user.
many linux distributions also have environment variables preset with the current user that you could try to read with System.getProperty(), but the whoami is probably a bit more robust.
I just noticed there is also a Java System Property user.name that is supposed to hold the user account name, try reading that with System.getProperty()
I'm using a bash script to start a java program/process. The bash script prompts for username and password and should supply these to the java process. I don't want to supply these as parameters for the java program so they can be seen as clear text using the shell "ps" command. So I don't want any of the following:
- java MyClass <clearTextPassword>
- java -Dpass=<clearTextPassword>
Are there any recommended ways to supply the password to the java process from a shell script?
Thanks in advance for any suggestions.
Best regards Trym
if you have coded the program yourself, its better to design your program such that it promts the user for password and use Console class's readPassword() to read the password from the command line
In this cases I create a file on disk (encrypted or not depending on your level of security need). I modify the permission so that only controlled user can read it when executing the program
You could store the password in a properties file (you have different options when it comes to securing it. You can also forgo a password entirely and use a public Key
You could pass a hashed version of the password. For example, provide a timestamp, and a MD5 of timestamp and password concatenated together. This is of course if you have control over the process code and can work with an hashed version.
So, it's a little unconventional, but I'm basically producing a Java App which I need to have access the /etc/hosts file.
This file obviously cannot be edited without root privs. The program is for parents so they can disable their kids from viewing certain sites. How can I make this root access happen?
I have read somewhere that I might be able to open the application as root inside of MacOSX's terminal line, but the reason I'm doing this program in Java is so I can distribute it to some of my close friends who are not computer savy, and they can easily run it.
Is there anyway I can request root privs at the beginning of the app?
You can let the user start the app with superuser privilges using the sudo command.
sudo your-app
The user must be allowed to use superuser privileges. He willl be prompted for his password before executing the command. Look around this site for more infos about sudo.
Note: Another possibility would be using the SUID bits directly. This is not very clever, because anyone starting the app would have superuser privileges. `sudo`` is the wrapper of choice for granting access for exactly that reason.
I assume that you use a unix-based system.
You can ask the users to make the program be owned by root and put the SUID bit on it (chmod 4555 on the file for example).
This way any user can launch it and the program will be executed with root privileges and will be easy to use.
Correction: Apparently you can't apply the SUID a java program according to this link (it is barely the same for scripts).
Just do a wrapper in C instead with the SUID bit:
#include <unistd.h>
int main(){
system("java main");
return 0; }
For more details concerning the SUID bit check this out.
If the input is interactive, i.e. from the console, I want to print a command prompt e.g. ">"
But if it is redirected e.g. from a file, then I do not want to prompt.
System.in is an abstract InputStream which does not appear to have any method for this.
Maybe you could use instanceof if the concrete type is different?
As well, if System.out is redirected to a file I also do not want to prompt
AFAIK, there is no way to do this in pure Java, and even doing it in JNI / JNA would be complicated.
An alternative might be to use the new Console API introduced in JDK 1.6. This allows you to try to get a reader/writer for the console. If it succeeds, the result is guaranteed to be interactive ... in the sense that you mean.
A second alternative would be to do the "check for interactivity" in the wrapper script that you use to launch your application, and pass the information to Java via the system properties. For instance, on a GNU/Linux system the tty(1) command can be used to tell if stdin is a connected to a "tty" device.
Note that there are other ways to deal with a requirement to avoid unwanted prompts when running non-interactively:
If System.out is redirected to a file I also do not want to prompt.
(I think you might mean that System.in is redirected. That is the normal way to non-interactively run an application that normally takes interactive input from the user ...)
The alternatives include:
You could modify the program to write the prompts to (say) System.err and redirect that to a different place.
You could modify the program to have options that mean "don't prompt" or "take input from a file".
Since Java 6 there is the method java.lang.System.console():
Whether a virtual machine has a console is dependent upon the
underlying platform and also upon the manner in which the virtual
machine is invoked. If the virtual machine is started from an
interactive command line without redirecting the standard input and
output streams then its console will exist and will typically be
connected to the keyboard and display from which the virtual machine
was launched. If the virtual machine is started automatically, for
example by a background job scheduler, then it will typically not have
a console.
If this virtual machine has a console then it is represented by a
unique instance of this class which can be obtained by invoking the
java.lang.System.console() method. If no console device is available
then an invocation of that method will return null.