I am writing a server application with Java servlets and at some point, a Python script that was uploaded by a user has to be executed. Is it possible to create a process with restrictions like only beeing able to access a certain directory (probably using ProcessBuilder)?
I already had a look at pysandbox, but I am not sure if this alone is a safe enough measure when executing an unknown Python script.
All the script has to do is process a given String using certain libraries and return a String using the print function.
Is my approach correct or is there a better way to execute an unknown script?
As a forward to my answer, whitelisting and blacklisting only go so far and are proven easily broken by the most determined of hackers. Don't bother with these styles of security.
About as safe as you are going to get is to use pypy-sandbox it creates an OS level sandbox and tries to isolate processes that could lead to nasty execution.
For real security you probably want something more like this following model.
Using SELinux as the host fire up a virtual machine running SELinux
Disable all ports except for SSH and ensure patches are up to date
Upload the code to a non executable directory.
Chroot and ulimit all the things
Execute the code through pypy-sandbox
Destroy the machine when execution is complete
Or maybe I am just paranoid.
Related
We can view bash commands history. It is stored normally in ~/.bash_history. For the same reason it is not recommended to send a curl request along with certificates and passwords.
But when I execute the same curl command using Runtime class in java Runtime.getRuntime().exec(command); I don't see this in the bash history.
It makes sense as this is done under the Runtime object and not executed from terminal. So where can I get the history of curl when done from Java using Runtime class?
Also is it safe to use Runtime class instead of actually storing certificate in a Trustore and using Https related Java classes?
Note: The certificates will be kept securely in Jenkins anyways.
How to view history of curl command executed using Runtime.getRuntime().exec?
You didn't run it with bash so, no, it is not in bash history. The answer to your question is OS dependent (and 'linux', in this sense, isn't detailed enough. What kind?) But, for example, as long as the command is running, ps auxww will probably show it, with the full command line including the arguments. As long as it is running, the directory representing the status of the process in the /proc virtual filesystem definitely lets you see the arguments it was invoked with.
Also is it safe to use Runtime class instead of actually storing certificate in a Trustore and using Https related Java classes?
That's just not how security works. It's shades of gray, not black and white. However, starting a subprocess for this is definitely a much darker gray (far less safe) than using java itself: As long as it is running, that subprocess arguments can be seen. The version of whatever command you invoke is less controllable (are you going to hash the executable? How would you know that the executable isn't being changed on you? This is of course entirely fine if you know who administrates the box and trust them, but that gets back to that shades of gray thing: If that part doesn't matter, sure, then this part is less problematic (heck, if you are the only one with an ssh login to this box, and only run trusted software, you can write the password across 50 files with global readability all over the file system and it wouldn't matter - and yet nobody is going to go on record and just make a blanket statement that this is 'safe'!).
So the idea is a kind of virtual classroom (a website) where students uploads uncompiled .java files, our server will compile it and execute it through C# or PHP, the language doesn't matter, creating a .bat file and get the feedback of the console if the program compiled correctly or not and if the execution was correct based on some pre-maded test, so far our tests did work but we have completely no control on what's inside the .java file so we want to stop the execution if some criterias did happen, i.e. an user input, infite loop, sockets instances, etc... I've digging on internet if there's a way to configure the java environment to avoid this but so far can't find anything, and we don't want our backend language to go through the file to check this things cause will be a completly mess up
Thanks for the help
You could configure a security manager, but it doesn't have a very good track record of stopping a determined attacker, and doesn't do resource limiting anyways.
You could load the untrusted code with a dedicated class loader that only sees white-listed classes.
Or you could use something like docker to isolate the process at the operating system level. This could also limit its cpu and memory consumption.
I'd probably combine these approaches, but some risk will remain in either case.
(Yes, I realize that is complex, but safely sandboxing arbitrary java code is a hard problem.)
I'm running a J2SE application that is somewhat trusted (Minecraft) but will likely contain completely un-trusted (and likely even some hostile) plugins.
I'd like to create a plugin that can access the GPIO pins on the Raspberry PI.
Every solution I've seen requires that such an app be given sudo-superpowers because gpio is accessed through direct memory access.
It looks like the correct solution is to supply a command-line option like this:
-Djava.security.policy=java.policy
which seems to default you to no permissions (even access to files and high ports), then add the ones your app needs back in with the policy file.
In effect you seem to be giving Java "sudo" powers and then trusting java's security model to only give appropriate powers out to various classes. I'm guessing this makes the app safe to run with sudo--is this correct?
Funny that I've been using Java pretty much daily since 1.0 and never needed this before... You learn something new every day.
[Disclaimer: I'm not very convinced by the Java security model.]
The way I would solve this is to have the code that needs to access the hardware run as a separate privileged process, then have your Java application run as an unprivileged process and connect to the privileged process to have it perform certain actions on its behalf.
In the privileged process, you should check with maximum distrust each request whether it is safe to execute. If you are afraid that other unprivileged processes might connect to the daemon too and make it execute commands it shouldn't, you could make its socket owned by a special group and setgid() the Java application to that group by a tiny wrapper written in C before it is started.
Unix domain sockets are probably the best choice but if you want to chroot() the Java application, a TCP/IP socket might be needed.
Is it possible to stop an application in windows using java code ?
I'd like to create a program which is like a shortcut to stop an application on my pc. Is it possible using ProcessBuilder ? Thank you
Plain Java, without native access? No.
ProcessBuilder lets you control processes that you started from within the Java application, but it doesn't give you control to processes that were started by other processes.
As per user988052's comment, you can use pskill from the Sysinternals Suite to accomplish this through Runtime.exec. pskill uses the TerminateProcess function call. You can also call this function with JNI (or some other native caller, like JNA, NLink, etc.), but you'll need to obtain a handle to the process via the OpenProcess function call.
Is it possible to stop an application in windows using java code ? ... Is it possible using ProcessBuilder ?
Only if you launched the application from the same Java application that you are trying to fill it from.
Other than that, you need to resort to running a Windows-specific command to do the killing ... or something based on JNI to make native Windows library calls.
The other complications are that you may not be able to kill certain processes due to permissions issues, and some process may refuse to be killed.
I believe the JRE does not provide an API for system processes. ProcessBuilder can create system processes, but it cannot provide you with a Process object for a process created outside the JVM. I believe that is a philosophical decision on the part of the Java folks, to avoid certain OS-specific tasks where possible. You might think that every OS has pids, or that they all have some kind of kill message, but Java runs on lots of OSes, some of them quite strange.
You could make native code to do it and wrap that with JNI, but that would be wasteful. As Mr 988052 says, I suggest you execute a system-specific command through Runtime.exec or ProcessBuilder. You would need to decide which OSes you want to support, and be sure to get the commands (and the OS-detection code) right for each one.
I'm trying to develop an application that just before quit has to run a new daemon process to execute the main method of a class.
I require that after the main application quits the daemon process must still be in execution.
It is a Java Stored Procedure running on Oracle DB so I can't use Runtime.exec because I can't locate the java class from the Operating System Shell because it's defined in database structures instead of file system files.
In particular the desired behavior should be that during a remote database session I should be able to
call the first java method that runs the daemon process and quits leaving the daemon process in execution state
and then (having the daemon process up and the session control, because the last call terminated) consequentially
call a method that communicates with the daemon process (that finally quits at the end of the communication)
Is this possible?
Thanks
Update
My exact need is to create and load (reaching the best performances) a big text file into the database supposing that the host doesn't have file transfer services from a Java JDK6 client application connecting to Oracle 11gR1 DB using JDBC-11G oci driver.
I already developed a working solution by calling a procedure that stores into a file the LOB(large database object) given as input, but such a method uses too many intermediate structures that I want to avoid.
So I thought about creating a ServerSocket on the DB with a first call and later connect to it and establish the data transfer with a direct and fast communication.
The problem I encountered comes out because the java procedure that creates the ServerSocket can't quit and leave an executing Thread/Process listening on that Socket and the client, to be sure that the ServerSocket has been created, can't run a separate Thread to handle the rest of the job.
Hope to be clear
I'd be surprised if this was possible. In effect you'd be able to saturate the DB Server machine with an indefinite number of daemon processes.
If such a thing is possible the technique is likely to be Oracle-specific.
Perhaps you could achieve your desired effect using database triggers, or other such event driven Database capabilities.
I'd recommend explaining the exact problem you are trying to solve, why do you need a daemon? My instict is that trying to manage your daemon's life is going to get horribly complex. You may well need to deal with problems such as preventing two instances being launched, unexpected termination of the daemon, taking daemon down when maintenance is needed. This sort of stuff can get really messy.
If, for example, you want to run some Java code every hour then almost certanly there are simpler ways to achieve that effect. Operating systems and databases tend to have nice methods for initiating work at desired times. So having a stored procedure called when you need it is probably a capability already present in your environment. Hence all you need to do is put your desired code in the stored procedure. No need for you to hand craft the shceduling, initiation and management. One quite significant advantage of this approach is that you end up using a tehcnique that other folks in your environment already understand.
Writing the kind of code you're considering is very intersting and great fun, but in commercial environments is often a waste of effort.
Make another jar for your other Main class and within your main application call the jar using the Runtime.getRuntime().exec() method which should run an external program (another JVM) running your other Main class.
The way you start subprocesses in Java is Runtime.exec() (or its more convenient wrapper, ProcessBuilder). If that doesn't work, you're SOL unless you can use native code to implement equivalent functionality (ask another question here to learn how to start subprocesses at the C++ level) but that would be at least as error-prone as using the standard methods.
I'd be startled if an application server like Oracle allowed you access to either the functionality of starting subprocesses or of loading native code; both can cause tremendous mischief so untrusted code is barred from them. Looking over your edit, your best approach is going to be to rethink how you tackle your real problem, e.g., by using NIO to manage the sockets in a more efficient fashion (and try to not create extra files on disk; you'll just have to put in extra elaborate code to clean them up…)