Remote class loading depends on the client fetching bytecode from an attacker-controlled location and executing it. Unsafe object factory execution uses a factory already present in the target classpath to instantiate objects or call methods with attacker-supplied attributes. The first needs network-delivered classes. The second abuses local components and can survive stronger JDK restrictions.
How the Two JNDI Paths Differ in Practice
Both attack styles abuse JNDI as a lookup mechanism, but they fail and succeed for different reasons. Remote class loading is a network-delivered execution path, so defenders can often stop it by blocking code download, tightening JDK behaviour, or preventing outbound reachability to attacker infrastructure. Unsafe object factory execution is a local-classpath abuse path, so the danger is often what is already present, not what can be fetched.
The practical distinction is that one depends on a remote payload arriving over the wire, while the other depends on a dangerous factory or gadget already being available to the target runtime. That makes the second path more resilient to some hardening measures, because the attacker is no longer asking the victim JVM to trust external bytecode, only to process attacker-controlled naming or attribute data in ways that trigger local behaviour.
When you are reviewing a suspected JNDI issue, the first question is whether the exploit path requires code download at all. If it does, network controls, JDK restrictions, and class-loading policy can materially reduce exposure. If it does not, you have to focus on classpath contents, object factory resolution, and whether the target application exposes any lookup path that can be shaped into object construction or method invocation.
Why the Bypass Works When Remote Loading Is Restricted
Remote class loading is comparatively easy to reason about because the defender can often point to a clear fetch-and-execute boundary. Unsafe object factory execution is harder because it turns a naming operation into local object creation, so the security boundary shifts from “can this host download code?” to “what trusted code is already installed, and what will it do with untrusted attributes?”
This is why the second technique can survive stronger JDK restrictions. If the runtime no longer permits remote bytecode loading, the attack may still succeed by selecting a factory that is already on the classpath and persuading it to instantiate, bind, or initialise an object in an unsafe way. The result is not necessarily arbitrary bytecode execution, but it can still be application compromise, unexpected outbound traffic, or execution of dangerous side effects inside trusted libraries.
That distinction matters operationally because a “blocked remote class loading” finding is not a full closure. It only tells you one execution route is gone. If the application still permits untrusted JNDI lookups and still has exploitable object factories available, the residual risk remains in the local runtime and library ecosystem rather than in the network delivery path.
What Practitioners Should Verify Before Calling the Issue Fixed
Remote loading and factory execution need different validation steps, and treating them as one class of bug leads to false confidence. A fix is only meaningful if it removes the code-download path and also prevents attacker-controlled data from reaching a local factory or gadget that can be triggered through JNDI resolution.
The cleanest review is to separate three checks: whether outbound class retrieval is blocked, whether any dangerous object factories are present in the deployed classpath, and whether the application ever resolves JNDI input that an attacker can influence. If only the first check passes, you still may have a viable local execution path.
- Confirm whether the runtime can still fetch classes from attacker-controlled locations.
- Inventory the deployed libraries and object factories that JNDI can resolve locally.
- Trace every user-influenced naming, URL, or attribute input that reaches a lookup call.
- Validate that mitigation changed behaviour, not just one configuration flag.
Practitioner takeaway: A remote class loading fix is usually a network and JVM-hardening story, while unsafe object factory execution is a classpath and data-flow story. Teams should treat them as related but distinct exposure paths, because closing one does not prove the other is gone.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK address the attack and risk surface, while CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | T1221 — Template Injection | JNDI abuse often turns trusted parsing or resolution into attacker-controlled execution behavior. |
| T1105 — Ingress Tool Transfer | Remote class loading depends on attacker-delivered code reaching the victim runtime over the network. | |
| Recommendation — Map JNDI abuse paths to T1221 and hunt for lookup-driven execution in affected applications. Apply T1105 detections and block outbound retrieval of attacker-hosted classes. | ||
| CIS Controls v8 | 6 — Access Control Management | Restricting who can trigger lookups and what code can execute reduces JNDI abuse exposure. |
| 8 — Audit Log Management | Lookup abuse and unexpected object instantiation should be observable for investigation and response. | |
| Recommendation — Enforce least-privilege access around any component that can invoke JNDI resolution. Log JNDI lookup activity and alert on anomalous object-factory execution paths. | ||
Related resources from NHI Mgmt Group
- What is the difference between prompt injection and LLM remote code execution?
- What is the difference between a remote code execution flaw and a privilege escalation flaw in an edge appliance?
- What is the difference between command injection and remote code execution in a Rust application context?
- What is the difference between token theft and privilege escalation in managed identity attacks?