Code injection is caused as a result of malicious user input being can occur when untrusted input is injected into dynamically constructed code. The One obvious source of potential vulnerabilities is the use of JavaScript from Java code. The javax.script
package provides utilities to use various scripting engines from Java code. If misused, an attacker can consists of interfaces and classes that define Java scripting engines and a framework for the use of those interfaces and classes in Java code. Misuse of the javax.script
API permits an attacker to execute arbitrary code on the target system.
This class of vulnerabilities is dangerous because any violations of secure coding practices in dynamically generated code cannot be statically determinedguideline is a specific instance of IDS00-J. Prevent SQL injection.
Noncompliant Code Example
This noncompliant code example uses dynamically obtained incorporates untrusted user input in into a javascript JavaScript statement , that is responsible for printing the input. A hostile user may enter specially crafted input parameters :
Code Block | ||
---|---|---|
| ||
private static void evalScript(String firstName) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
engine.eval("print('"+ firstName + "')");
}
|
An attacker can enter a specially crafted argument in an attempt to inject malicious javascript. The firstName
string contains javascript JavaScript. This example shows a malicious string that contains JavaScript code that can create a file or overwrite an existing file on the system running the vulnerable Java codea vulnerable system.
Code Block | |||||
---|---|---|---|---|---|
| |||||
// Windows based target's file path is being used String firstName = "dummy\'); var bw = new JavaImporter(java.io.BufferedWriter); var fw = new JavaImporter(java.io.FileWriter); with(fw) with(bw) { bwr = new BufferedWriter(new FileWriter(\"c://somepath//somefile.txtconfig.cfg\")); bwr.write(\"some text\"); bwr.close(); } // "; evalScript(firstName); |
The script in this example prints
and then writes "
dummy"
to a configuration file called "
some text"config.cfg
. An actual exploit can execute arbitrary code.
Compliant Solution (Whitelisting)
The best defense against code injection vulnerabilities is to prevent the inclusion of executable user input in code. User input used in dynamic code must be sanitized, for example, to ensure that it contains only valid, whitelisted characters. Sanitization is best performed immediately after the data has been input, using methods from the data abstraction used to store and process the data. Refer to IDS00-J. Sanitize untrusted data passed across a trust boundary for more details. If special characters must be permitted in the name, they must be normalized before comparison with their equivalent forms for the purpose of input validation. This compliant solution uses whitelisting to prevent unsanitized input from being interpreted by the scripting engine.
Code Block | ||
---|---|---|
| ||
private static void evalScript(String firstName) throws ScriptException { // Allow only alphanumeric and underscore chars in firstName // (modify if firstName may also include special characters) if (!firstName.matches("[\\w]*")) { // String does not match whitelisted characters throw new IllegalArgumentException(); } ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval("print('"+ firstName + "')"); } |
Compliant Solution
...
The best defense against code injection vulnerabilities is to avoid including executable user input in code. If some dynamic code requires certain user input, the input should be sanitized. For example, a top-level method should ensure that the string firstName
contains only valid characters. Refer to the guideline IDS08-J. Sanitize before processing or storing user input for more details.
(Secure Sandbox)
An alternative approach is to In addition, a complementary policy is to create a secure sandbox using a security manager (ENV30see SEC54-J. Create a secure sandbox using a Security Manager). This approach is akin to the one discussed in the first compliant solution of IDS12-J. Prevent XML external entity attacks. security manager.) The application should not allow prevent the script to execute from executing arbitrary commands, such as querying the local file system. The two-argument form of of doPrivileged()
can can be used to lower privileges when the application must operate with higher privileges, but the scripting engine must not. The The RestrictedAccessControlContext
strips reduces the permissions granted in the default policy file and add its own (when required) while creating the protection domain. Refer to the guideline SEC00-J. Follow the principle of least privilege for more details on to those of the newly created protection domain. The effective permissions are the intersection of the permissions of the newly created protection domain and the systemwide security policy. Refer to SEC50-J. Avoid granting excess privileges for more details on the two-argument form of doPrivileged()
.
This compliant solution illustrates the use of an AccessControlContext
in the two-argument form of doPrivileged()
.
Code Block | ||
---|---|---|
| ||
class ACC { private static class RestrictedAccessControlContext { private static final AccessControlContext INSTANCE; static { INSTANCE = new AccessControlContext( new ProtectionDomain[] { new ProtectionDomain(null, null) // First sanitize firstName No permissions }); } } private static void evalScript(final String firstName) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); final ScriptEngine engine = manager.getEngineByName("javascript"); // Restrict permission using the two-argument form of doPrivileged() try { AccessController.doPrivileged( new PrivilegedExceptionActionPrivilegedExceptionAction<Object>() { public Object run() throws ScriptException { engine.eval("print('" + firstName + "')"); return null; } }, // From nested class RestrictedAccessControlContext.INSTANCE); } catch (PrivilegedActionException pae) { // Handle error } } |
Risk Assessment
}
}
|
This approach can be combined with whitelisting for additional security.
Applicability
Failure to prevent Failing to prevent against code injection can result in the execution of arbitrary code.
...
Automated Detection
Tool |
---|
Version |
---|
Checker |
---|
Description |
---|
Level
IDS17- J
high
likely
medium
P18
L1
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[API 06|AA. Java References#API 06]\] Package {{javax.script}}
\[[OWASP 08|AA. Java References#OWASP 08]\] [Code injection in Java|http://www.owasp.org/index.php/Code_injection_in_Java] |
The Checker Framework |
| Tainting Checker | Trust and security errors (see Chapter 8) | ||||||
Parasoft Jtest |
| CERT.IDS52.TDCODE | Validate potentially tainted data before it is used in methods that generate code |
Bibliography
...
FIO36-J. Do not create multiple buffered wrappers on an InputStream 09. Input Output (FIO) 09. Input Output (FIO)