Safeguard
Application Security•

ASVS 5.0 V1.3.8: Prevent JNDI Injection in Java

ASVS V1.3.8 requires sanitizing input used in JNDI lookups and configuring JNDI securely. See the settings and a test that catches remote lookups.

Safeguard Security Team
2 min read

ASVS 5.0 V1.3.8 (Level 2) requires that untrusted input is sanitized before it is used in Java Naming and Directory Interface (JNDI) queries, and that JNDI itself is configured so it cannot load remote objects. The rule exists because a lookup of an attacker chosen name can lead to remote code execution, as the Log4Shell incident showed.

Why it matters

A JNDI lookup such as ctx.lookup(name) can contact LDAP or RMI servers and, on older or misconfigured runtimes, load classes from them. If name comes from a request, an attacker points it at their own server and your JVM fetches and runs their code.

How to implement it

Do not pass user input to lookup. Map user choices to fixed names:

private static final Map<String, String> DATA_SOURCES = Map.of(
    "reports", "java:comp/env/jdbc/reports",
    "billing", "java:comp/env/jdbc/billing");

String jndiName = DATA_SOURCES.get(choice);
if (jndiName == null) throw new IllegalArgumentException("unknown source");
DataSource ds = (DataSource) new InitialContext().lookup(jndiName);

Then harden the runtime:

  1. Use a current JDK. Remote class loading through JNDI is disabled by default in modern releases (the trustURLCodebase properties default to false), and you should not turn them back on.
  2. Keep logging libraries and frameworks updated, and disable message lookups where the library offers it.
  3. Restrict outbound traffic from application servers so LDAP and RMI calls to the internet fail.
  4. Set a deserialization filter (jdk.serialFilter) to limit what JNDI can reconstruct.

How to test it

Send ${jndi:ldap://your-listener.example/a} in headers, parameters and logged fields, with a listener you control. No connection should arrive. Check for any call of lookup with a non constant argument.

Common mistakes

  • Validating the scheme and missing nested or obfuscated forms.
  • Relying on an upgrade without blocking egress.
  • Assuming only logging code does lookups.

Quick check

What is the best way to handle a user choice that selects a JNDI resource?

Map it through a fixed table to a known name. Never pass the user value to lookup.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.