In late 2022, a significant vulnerability—tracked as CVE-2022-42920—was uncovered in the popular Java library Apache Commons BCEL. This bug goes well beyond a minor coding error: It creates the opportunity for attackers to generate *arbitrary Java bytecode* by exploiting out-of-bounds writes in BCEL's APIs. Below, we’ll walk through what this means, how an exploit would work, and—most importantly—how to protect your apps.
What is Apache Commons BCEL?
BCEL (Byte Code Engineering Library) is a library that lets Java developers programmatically analyze, create, and modify Java bytecode. It powers many advanced frameworks (think: code analysis, runtime code transformations, and tools like static analyzers).
The Heart of the Problem
Certain APIs in BCEL—meant for operations like modifying methods, fields, or class attributes—suffered from insufficient bounds checking when writing data internally. That means, if an attacker manages to control input to these methods, they could manipulate them in such a way as to write data outside the intended space inside a bytecode array. This could allow an attacker to:
How would an attacker abuse this?
Imagine a web service that lets users upload code snippets or configurations, which get processed via BCEL to dynamically generate classes at runtime. If this service passes untrusted data into BCEL's "safe" APIs, a clever attacker could craft input that abuses the out-of-bounds vulnerability to sneak in code they shouldn't be able to.
Exploit Details
The exploit centers on the InstructionList, ConstantPoolGen, and similar classes. If an attacker can supply malicious values in a specific context, they could write a custom crafted input to BCEL, tricking it to "escape" the allowed bytecode and insert whole new instructions or even arbitrary method calls.
Suppose you use BCEL like this (very simplified)
import org.apache.bcel.generic.*;
import org.apache.bcel.classfile.*;
public class DynamicClassMaker {
public static byte[] makeClass(String className, List<Instruction> instructions) {
ClassGen cg = new ClassGen(className, "java.lang.Object", "AutoGen.java", Constants.ACC_PUBLIC, null);
ConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();
// BAD: Directly adding user-controlled instructions!
for (Instruction inst : instructions) {
il.append(inst);
}
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC, Type.VOID, Type.NO_ARGS, new String[] {}, "doSomething", className, il, cp);
cg.addMethod(mg.getMethod());
il.dispose();
JavaClass jc = cg.getJavaClass();
return jc.getBytes();
}
}
Now, imagine instructions contains attacker-supplied objects—crafted to exploit the out-of-bounds bug.
Proof-of-Concept (Simplified)
A real exploit would need to dig into BCEL internal classes and use very specific values (like manipulated InstructionHandle chains or specially encoded operands) to trigger the bug. Here's a theoretical snippet hinting how payloads could be abused (in pseudocode):
// Attacker crafts an Instruction with manipulated length field or offset
Instruction evilInst = new CustomInstruction() {
public int getLength() { return Integer.MAX_VALUE; } // triggers out-of-bounds
...
};
// Pass to API expecting a normal instruction
List<Instruction> payload = Arrays.asList(evilInst);
makeClass("MaliciousClass", payload);
By exploiting unchecked array writes, the attacker could overwrite BCEL's structure with attacker-supplied bytecode—effectively making the library generate unsafe code.
Severity and Impact
- CVSS Score: High, details here
If your application:
- Does NOT use attacker-controlled input to fill BCEL APIs? You're relatively safe, but upgrade anyway.
- DOES use user-controlled data? *You are at risk!* An attacker could escalate their access or run malicious code.
How to Fix It
Upgrade BCEL to at least version 6.6..
Upgrade instructions here (official BCEL Changelog)
Mitigations, if upgrade is impossible
- Never pass user-controlled data to BCEL (or filter/validate input thoroughly)
References
- Official CVE-2022-42920 Info
- Apache Commons BCEL Project Page
- Security Advisory from Apache
- Release Notes & Changelog for BCEL 6.6.
Conclusion
CVE-2022-42920 is a reminder that even utility libraries can become major attack vectors when exposed to untrusted input. If you use Apache Commons BCEL in your stack (especially web-facing systems or microservices), upgrade right away. Don’t let attackers write custom Java bytecode into your app!
Timeline
Published on: 11/07/2022 13:15:00 UTC
Last modified on: 11/08/2022 04:20:00 UTC