nowadays you can read much about code injection, exploits, buffer-, stack- and heap-overflows etc. leading to inject and run code. I wonder what of this stuff is relevant for Java.
I know, there are no pointers in the Java language. But doesn't the JVM organize data in heaps and / or stacks?
I know there is no eval function (like in PHP) so you cant easily use an input as Java-code. I am not so sure whats going on on bytecode level.
I think XSS is possible, for example in an Java EE application, when no inputs are filtered. But isn't this more a JavaScript injection, because the injected code runs in the browser and not in the JVM?
So which code injections are possible with java and which are not? And is this true for other Java platform languages, too?
Thanks in advance.
A java program itself is pretty much not vulnerable to code injection. However, all the native code that supports the app is vulnerable to all the different kinds of code injection - this includes the JVM and all native code parts in the app or its libraries.
Also, there are a few more things to consider:
Anything where java is used as a gateway to other systems is possible:
SQL Injection
XSS (which is in the end nothing more than JavaScript Injection)
If the java program is itself a interpreter/compiler of some kind, it might be possible to inject code into your interpreted language/compiled program (this includes using your program as a java compiler...)
And of course if you can get the java program to write a file to disk that contains code (be it native, java or something else) you might be able to get it executed by other means (which can be a different vulnerability in your app, the os or another app) - this is not direct code injection but quite similar in effect.
If the server application creates bytecode at runtime (for example with BCEL or Javassist), and if this creation can be influenced by user input, then a code injection is possible.
However, if you application uses no magic (which should be 99% of all applications), it will not be possible.
There are a couple ways in which Java code could be injected into an application such as using the scripting API or dynamic JSP includes.
The code below allows a user to inject arbitrary Javascript into Java's script engine.
import javax.script.*;
public class Example1 {
public static void main(String[] args) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
System.out.println(args[0]);
engine.eval("print('"+ args[0] + "')");
} catch(Exception e) {
e.printStackTrace();
}
}
}
In this case, the attacker decides to inject code that creates a file on the file system.
hallo'); var fImport = new JavaImporter(java.io.File); with(fImport) { var f = new File('new'); f.createNewFile(); } //
check owasp website for more examples
You could write a web service that accepted a Java code snippet, wrapped it in a class/method declaration, saved it to disk, ran the compiler on it and then dynamically loaded and executed the result. So code injection is certainly possible.
But with typical Java implementations, it's perhaps not very efficient because of the relatively heavyweight compilation process (it might still be practical for some apps though).
Code injection is highly relevant with SQL because the "first guess" of many beginners is to use string concatenation to insert variables into a statement. But it rarely crops up as an idea amongst Java programmers. So that's the reason it isn't much of a concern.
If Java compilers become exposed as light-weight library services, then you'd have something much closer to the equivalent of eval and therefore it might start to become a relevant concern.
If it was possible, Java would already have been dead for long.
On the other hand, SQL injections are very easy to avoid by using PreparedStatement to store user-controlled input and XSS is also very easy to avoid by using <c:out/> for (re)displaying user-controlled input at the webpage.
Unless you are doing weird things on the server (like dynamically generating code, etc), it is impossible to bo vunerable for code injection.
Although I can think of an (ugly) situation where the application dynamically creates a JSP based on user input. That JSP will be translated to Java code, which is being compiled to byte-code by the web container, and then executed. This could introduce an injection point. But generating JSP's dynamically normally doesn't make any sense.
You can't inject Java. But if you are not careful, people could inject Javascript (i.e. XSS as you mention) or SQL. There are heaps and stacks, but no way to get to them.
You can't inject java, but all web applications are vulnerable to XSS if the input is not properly filtered. Also any application that interacts with a sql database can be vulnerable to SQL injection. To avoid this you will want to look into Parameterized Queries.
It is certainly more difficult, if you compare it to interpreted languages. However, the JVM supports scripting languages like JavaScript, and one of the example above demonstrates injection when JavaScript is at play.
The JVM also supports scripting with Groovy, which is the the Java scripting equivalent. So, if you know that this is what is happening behind the scenes, you can use something similar to this:
Class scriptClass = new GroovyClassLoader().parseClass( new File( "test.groovy" ) ) ;
Of course, you will have to get test.groovy on the server somehow, which is another story. See this thread for more details: Calling a Groovy function from Java. Groovy compiles to byte code on the fly and it is automatically loaded into the JVM.
I've seen enterprise applications written in Java expose a Scripting Web Console, where you could supply an entire Groovy file and execute it with the system still running ... with Admin privileges. Behind it uses the JVM's scripting capabilities. You could also use it with JavaScript.
Here are the scripting languages supported by the JVM as of July, 2020:
Java
Kotlin
Scala
Groovy
Clojure
Fantom
Ceylon
Jython
JRuby
Frege
Xtend
Golo
Concurnaas
Yeti
See this article for more details.
Bottom line, code injection in Java is not as easy as it is in other languages, especially interpreted ones, like JavaScript, Ruby, PHP, etc.
Related
I am working on building a Java service which will take as input below:
Pre-compiled java function as bytecodes and
Relevant parameters
Now it's also possible that parameters is already available in the service or it might fetch them from some other service so currently we are keeping it optional.
The main question is my service needs to execute that bytecode function and return the result or just execute the task depending on whether that function returns anything or not.
Bytecode come from a legacy application developed on JRuby. As the legacy code is complex(and working!) and we don't want to take the pain of re-writing same thing again. Ultimately even if we re-write(just syntax change) end result is going to be just bytecode. So if we aleady have bytecode this approach makes sense.
I haven't done anything similar before. But may be loading bytecode via classloader help which I will try. Hoping to gain from experienced users here.
I'm interested in learning secure coding best practices (specifically for Java apps) and I'm reading OWASP's Secure Coding Practices checklist. Under their Memory Management section they state the following:
Avoid the use of known vulnerable functions (e.g., printf, strcat, strcpy, etc.).
I'm not a C/C++ developer, but this must mean that the above functions have security vulnerabilities in them. I ran a couple of searches for vulnerable Java methods and all I came up with was this CVE.
What Java SE/EE methods (if any) apply to this advisory from OWASP?
For C APIs, yes, you can cause problems with those functions by doing unintentional memory corruption if your parameters are not carefully checked.
In Java, since all operations are automatically checked, this class of memory corruption exploit should not happen (barring bugs in the implementation).
Those are C functions that are particularly prone to buffer overflow and format string attacks.
Java doesn't typically have those problems, but the same rule of thumb applies -- don't trust your inputs.
Reflection & Serialization
Java's reflection APIs can be a source of vulnerabilities.
If an attacker can cause part of a string they give you to be treated as a class, method, or property name, then they can often cause your program to do things that you did not intend.
For example,
ObjectInputStream in = ...;
MyType x = (MyType) in.readObject();
will allow an attacker who controls content on in to cause the loading and initialization of any class on your CLASSPATH and allow calling any constructor of any serializable class on your CLASSPATH. For example, if you happen to have a JS or Python interpreter on your CLASSPATH, they may be able to get access to a String -> JavaScript/Python function class from where they might be able to gain access to more powerful methods via Java reflection.
javax.script
javax.script is available in Java 6 and allows converting strings into source code in an embedded scripting language. If untrusted inputs reach these sinks, they may be able to use the script engine's access to Java reflection to reach the file-system or shell to execute arbitrary user-ring instructions with the permissions of the current process's owner.
XML
Java is just as vulnerable to external entity attacks as other languages whereby external entities in an XML input can be used to include content from URLs from the local network.
If you don't hook into java.net.SocketFactory or use a SecurityManager to filter outgoing connections then any XML parse method that does not let you white-list URLs that appear in DTDs is vulnerable.
Runtime / ProcessBuilder
Also not Java specific, but Runtime and ProcessBuilder allow access to executables on the local file-system. Any attacker controlled strings that reach these can potentially be used to elevate permissions.
I encounter this issue when calculating the price for a product but the formula changes nearly every day because of marketing schemes, discounts, taxes...
So I think it would be great if I could write code such as the code below, so that I could change the script at runtime.
public BigDecimal calculate(String script) {
return (BigDecimal) ScriptEngine.execute(script);
}
Is there any way to implement this using Java?
Yes: Use the Scripting API.
There are implementations to run scripts written in JavaScript, Groovy, Python and lots of other languages.
[EDIT]
Since it was mentioned in the comments: Be wary of security issues.
There are several options:
You allow end-customers to supply scripts (say in a web form)
You don't allow customers to supply scripts; if a script needs to be changes an administrator or developer must start a specific tool.
You develop a system which only allows to execute "safe" scripts
Option #3 doesn't work (= only works for the most simple cases). There is a mathematical proof that a computer program can never tell what another program can potentially do without actually executing it.
So you can get away with option #3 if you don't allow to call methods (or only a very, very limited set of methods). But most scripting languages allow to access Java classes which means you can eventually get System.exit() or Runtime.exec(). This in turn means you have to write a parser which makes sure that the code doesn't contain something odd.
Which you will have to update every day because the customers will come up with new ... err ... interesting ways to use the feature.
Also chances are that you'll make a mistake - either the parser won't accept valid input or it will let malicious code pass. Given the complexity of the problem, the chance is between 99.9999% and 100%.
Option #1 means no security at all but after the third change, customers will berate you to adopt it. It will work for some time until the first script kiddie comes along and ruins everything. Guess whose fault that will be? The manager who hired his nephew... the kid?
So a human will have to eyeball the scripts, fix all the bugs in them and configure the system to run them. Option #2 will cause all kinds of griefs, too, but it will cause less grief, all things considered.
What language do you want "script" to be in?
One way to do this would be to use Javascript, and use a library like Rhino. This will let you execute some JS and get the output inside your code.
http://www.mozilla.org/rhino/
Sure, see Mozilla Rhino
You can use beanshell.jar - It is a standalone shell as well, but can easily be used to run uncompiled java code at runtime.
I'm developing a system that allows developers to upload custom groovy scripts and freemarker templates.
I can provide a certain level of security at a very high level with the default Java security infrastructure - i.e. prevent code from accessing the filesystem or network, however I have a need to restrict access to specific methods.
My plan was to modify the Groovy and Freemarker runtimes to read Annotations that would either whitelist or blacklist certain methods, however this would force me to maintain a forked version of their code, which is not desirable.
All I essentially need to be able to do is prevent the execution of specific methods when called from Groovy or Freemarker. I've considered a hack that would look at the call stack, but this would be a massive speed hit (and it quite messy).
Does anyone have any other ideas for implementing this?
You can do it by subclassing the GroovyClassLoader and enforcing your constraints within an AST Visitor. THis post explains how to do it: http://hamletdarcy.blogspot.com/2009/01/groovy-compile-time-meta-magic.html
Also, the code referenced there is in the samples folder of Groovy 1.6 installer.
You should have a look at the project groovy-sandbox from kohsuke. Have also a look to his blog post here on this topic and what is solution is addressing: sandboxing, but performance drawback.
OSGi is great for this. You can partition your code into bundles and set exactly what each bundle exposes, and to what other bundles. Would that work for you?
You might also consider the java-sandbox (http://blog.datenwerke.net/p/the-java-sandbox.html) a recently developed library that allows to securely execute untrusted code from within java.
Also see: http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html
I have a post-compilation step that manipulates the Java bytecode of generated classes. I'd like to make life as painless as possible for library consumers, so I'm looking at ways I can make this process automatic and (if possible) compiler agnostic.
The Annotation Processing API provides many of the desired features (automatic service discovery; supported by Eclipse). Unfortunately, this is aimed at code generators and doesn't support manipulation of existing artefacts:
The initial inputs to the tool are
considered to be created by the zeroth
round; therefore, attempting to create
a source or class file corresponding
to one of those inputs will result in
a FilerException.
The Decorator pattern recommended by the API is not an option.
I can see how to perform the step with a runtime agent/instrumentation, but this is a worse option than a manual build step as it would require anyone even peripherally touched by the API to configure their JVMs in a non-obvious manner.
Is there a way to plug into or wrap the compiler tool as invoked by javac? Has anyone successfully subverted the annotation processors to manipulate bytecode, no matter what the doc says?
The Groovy compiler is the only bytecode compiler which allows to hook into the compilation process (example: Generate bytecode to support the Singleton pattern)
The Annotation Processing API is not meant to change the code. As you have already found out, all you can do is install a classloader, examine the bytecode at runtime and manipulate it. It's braindead but it works. This follows the general "we're afraid that a developer could try something stupid" theme which you will find throughout Java. There is no way to extend javac. The relevant classes are either private, final or will change with the next version of Java.
Another option is to write annotated Java, for example you write a class "ExampleTpl.java". Then, you use a precompiler which expands the annotations in that file to get "Example.java". In the rest of the code, you use Example and ignore ExampleTpl.
For Eclipse, there is a bug report to automate this step. I'm not aware of any other work in this area.
It can be done.
Take a look at my blog post Roman Numerals, in our Java where an annotation processor is used to rewrite code. Limitation being that it works with Sun's javac only.