Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ TEST_MAVEN_ARTIFACTS = [
"org.assertj:assertj-core:3.27.6",
"org.jacoco:org.jacoco.core:0.8.14",
"org.mockito:mockito-core:5.20.0",
"org.mvel:mvel2:2.5.2.Final",
"org.openjdk.jmh:jmh-core:1.37",
"org.openjdk.jmh:jmh-generator-annprocess:1.37",
]
Expand Down
44 changes: 42 additions & 2 deletions maven_install.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
"__INPUT_ARTIFACTS_HASH": -1638807165,
"__RESOLVED_ARTIFACTS_HASH": -1440417829,
"__INPUT_ARTIFACTS_HASH": 1624596153,
"__RESOLVED_ARTIFACTS_HASH": 1478602772,
"conflict_resolution": {
"com.google.code.gson:gson:2.8.6": "com.google.code.gson:gson:2.8.9",
"com.google.j2objc:j2objc-annotations:2.8": "com.google.j2objc:j2objc-annotations:3.1",
Expand Down Expand Up @@ -536,6 +536,12 @@
},
"version": "5.20.0"
},
"org.mvel:mvel2": {
"shasums": {
"jar": "77d14116dfad5259aa3c21e177fb5455b2c86f4873f49828fdb6000ebe77660d"
},
"version": "2.5.2.Final"
},
"org.objenesis:objenesis": {
"shasums": {
"jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb"
Expand Down Expand Up @@ -2164,6 +2170,34 @@
"org.mockito.stubbing",
"org.mockito.verification"
],
"org.mvel:mvel2": [
"org.mvel2",
"org.mvel2.asm",
"org.mvel2.asm.signature",
"org.mvel2.ast",
"org.mvel2.compiler",
"org.mvel2.conversion",
"org.mvel2.debug",
"org.mvel2.integration",
"org.mvel2.integration.impl",
"org.mvel2.jsr223",
"org.mvel2.math",
"org.mvel2.optimizers",
"org.mvel2.optimizers.dynamic",
"org.mvel2.optimizers.impl.asm",
"org.mvel2.optimizers.impl.refl",
"org.mvel2.optimizers.impl.refl.collection",
"org.mvel2.optimizers.impl.refl.nodes",
"org.mvel2.sh",
"org.mvel2.sh.command.basic",
"org.mvel2.sh.command.file",
"org.mvel2.sh.text",
"org.mvel2.templates",
"org.mvel2.templates.res",
"org.mvel2.templates.util",
"org.mvel2.templates.util.io",
"org.mvel2.util"
],
"org.objenesis:objenesis": [
"org.objenesis",
"org.objenesis.instantiator",
Expand Down Expand Up @@ -2784,6 +2818,7 @@
"org.junit.platform:junit-platform-reporting",
"org.junit.platform:junit-platform-testkit",
"org.mockito:mockito-core",
"org.mvel:mvel2",
"org.objenesis:objenesis",
"org.openjdk.jmh:jmh-core",
"org.openjdk.jmh:jmh-generator-annprocess",
Expand Down Expand Up @@ -2945,6 +2980,11 @@
"org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener"
]
},
"org.mvel:mvel2": {
"javax.script.ScriptEngineFactory": [
"org.mvel2.jsr223.MvelScriptEngineFactory"
]
},
"org.openjdk.jmh:jmh-generator-annprocess": {
"javax.annotation.processing.Processor": [
"org.openjdk.jmh.generators.BenchmarkProcessor"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ object ExpressionLanguageInjection {
private const val SPRING_EXPRESSION_LANGUAGE_ATTACK = "T($HONEYPOT_CLASS_NAME).el()"
private const val ELPROCESSOR_JEXL_LANGUAGE_ATTACK =
"\"\".getClass().forName(\"$HONEYPOT_CLASS_NAME\").getMethod(\"el\").invoke(null)"
private const val MVEL_ATTACK = "Runtime.getRuntime().exec(\"jazze\")"

init {
require(EXPRESSION_LANGUAGE_ATTACK.length <= 64) {
Expand All @@ -46,6 +47,9 @@ object ExpressionLanguageInjection {
require(ELPROCESSOR_JEXL_LANGUAGE_ATTACK.length <= 64) {
"Expression language exploit must fit in a table of recent compares entry (64 bytes)"
}
require(MVEL_ATTACK.length <= 64) {
"MVEL exploit must fit in a table of recent compares entry (64 bytes)"
}
}

@MethodHooks(
Expand Down Expand Up @@ -193,4 +197,51 @@ object ExpressionLanguageInjection {
val expr = arguments[0] as? CharSequence ?: return
Jazzer.guideTowardsContainment(expr.toString(), ELPROCESSOR_JEXL_LANGUAGE_ATTACK, hookId)
}

@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "eval",
)
@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "evalToString",
)
@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "evalToBoolean",
)
@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "compileExpression",
)
@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "compileGetExpression",
)
@MethodHook(
type = HookType.BEFORE,
targetClassName = "org.mvel2.MVEL",
targetMethod = "compileSetExpression",
)
@JvmStatic
fun mvelEval(
method: MethodHandle?,
thisObject: Any?,
arguments: Array<Any>,
hookId: Int,
) {
if (arguments.isEmpty()) return
val message =
when (val arg0 = arguments[0]) {
is String -> arg0
is CharArray -> String(arg0)
else -> throw IllegalArgumentException("Unexpected type for arguments[0] in ExpressionLanguageInjection hook")
}
Jazzer.guideTowardsContainment(message, MVEL_ATTACK, hookId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ java_junit5_test(
"@maven//:org_apache_commons_commons_jexl",
"@maven//:org_junit_jupiter_junit_jupiter_api",
"@maven//:org_junit_jupiter_junit_jupiter_params",
"@maven//:org_mvel_mvel2",
"@maven//:org_springframework_cloud_spring_cloud_function_context",
"@maven//:org_springframework_cloud_spring_cloud_function_core",
],
Expand Down
7 changes: 6 additions & 1 deletion sanitizers/src/test/java/com/example/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ java_fuzz_target_test(
srcs = [
"ExpressionLanguageInjection.java",
],
allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh"],
allowed_findings = [
"com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh",
"com.code_intelligence.jazzer.api.FuzzerSecurityIssueCritical",
],
tags = ["dangerous"],
target_class = "com.example.ExpressionLanguageInjection",
target_method = method,
Expand All @@ -66,11 +69,13 @@ java_fuzz_target_test(
"@maven//:javax_validation_validation_api",
"@maven//:org_apache_commons_commons_jexl",
"@maven//:org_junit_jupiter_junit_jupiter_api",
"@maven//:org_mvel_mvel2",
],
) for method in [
"fuzzValidator",
"fuzzEval",
"fuzzJexlExpression",
"fuzzMVELExpression",
]]

java_fuzz_target_test(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.commons.jexl2.JexlException;
import org.apache.commons.jexl2.MapContext;
import org.junit.jupiter.api.BeforeEach;
import org.mvel2.MVEL;

public class ExpressionLanguageInjection {
private static final Validator validator =
Expand Down Expand Up @@ -70,4 +71,12 @@ void fuzzJexlExpression(@NotNull String data) {
} catch (JexlException | StringIndexOutOfBoundsException ignored) {
}
}

@FuzzTest
void fuzzMVELExpression(@NotNull String data) {
try {
MVEL.executeExpression(MVEL.compileExpression(data));
} catch (Throwable ignored) {
}
}
}