(The whole discussion why a logging mechanism should support the whole JDNI stuff is still perfectly valid).
(The whole discussion why a logging mechanism should support the whole JDNI stuff is still perfectly valid).
The log4j vulnerability shares some common traits, but it's completely different at the core. It's not a problem of sanitization, and I'd argue it's not a problem of escaping either (though escaping could fix it). It's a problem with an obscure feature that is left with insecure defaults, and is (was?) unknown to the vast majority of developers who integrate the library in their apps.
Agreed that this is not a sanitisation attack, but i think that means it is a format string attack:
https://owasp.org/www-community/attacks/Format_string_attack
It requires a couple of other loopholes, related to JNDI, to work, but that is the first step which goes wrong.
Now, I think format string is not entirely right, either. That's more related to `printf`, which splits code (the format string) and data (the varargs). But log4j actually mixes code and data into one string. In the OWASP frame work, I think the more generic variant of format string attacks would be https://owasp.org/www-community/attacks/Code_Injection (that's actually linked under "related" for the format string attacks).
OWASP lives mostly in the web world, but links to CWE-77 (Command Injection, https://cwe.mitre.org/data/definitions/77.html), which is pretty generic. And log4shell matches the description just nice: 1. Data from untrusted source: yes; 2. data is part of a string that's executed: interpreted, which I think qualifies as a yes; 3. the execution gives capabilities the attacker would not have other wise: oh yes!
So it's probably safe to claim that this could fall under CWE-77 (too bad CVEs rarely use CWEs).
Now, CWE-77 (Command Injection) is a child of "CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')" https://cwe.mitre.org/data/definitions/74.html. Which states "The most classic instantiations of this category of weakness are SQL injection and format string vulnerabilities." - that's probably why the both of us thought of the the two of these! :) And even if CWE-77 is to specialized (this could be argued) CWE-74 should be a good match, quoting CWE-74: "The software constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component" [end quote].
Funnily, CWE-74 is a child of https://cwe.mitre.org/data/definitions/707.html - "Improper Neutralization". Which says neutralization can be done by (among others): "[...] transformation of the input/output to be "safe" using techniques such as filtering, encoding/decoding, escaping/unescaping, quoting/unquoting, or canonicalization [...]"
:) Thanks for triggering me on this.
Also I said "similar class", not "strictly equivalent". Both instances are a case of "user input handled as code, not as data". Now with SQLi the problem is widely known (but sadly still happens) and we have techniques like parameter binding to outright avoid the problem. The same techniques are among the <edit>theoretical</edit> possibilities to avoid the problem with log4j.
Though I agree, the problem are the insecure defaults (JNDI enabled) and that seemingly every java dev used log4j but wasn't aware of the "${}"-expressions. I just pointed out that this "trend of neglect" [sry, non-native speaker here<edit>, but I hope you get what I mean?</edit>] seems to continue: Everyone and their CISO is now aware that attackers can abuse JNDI and the whole mitigation recommendations (<edit>e.g.</edit> remove JDNI classes) so far was primarily focused on that. Still, even if JNDI wasn't a thing, the "${}"-expressions can still be abused (it's just more specialized now and not a huge pwn fest), requiring mitigations beyond disabling JNDI. Just look at the reporting for more examples of ignorance: When this started to explode, there were some who thought blocking the string "${jdni" in their WAF would be enough (and maybe it helped against script kiddies), but a smart attacker just used/uses a string like "${${env:randomstring:-j}dni[...]" defeating the simple filters...
Another example: A "transformation" that's a "sanitation" but not "escaping" would be replacing all occurrences of "<" with "<" (among others!). It surely doesn't add escape characters (e.g. \), but instead replaces the problematic substring with a replacement string that makes the string safe to display on a website. Of course you'll want to replace user-supplied "<" with "&lt;".
(btw, thanks for that it's "sanitation" and not "sanitization" ^^).
Now a Google search finds instances where sanitization/sanitation also includes techniques beyond filtering: https://www.webopedia.com/definitions/input-sanitization/ https://hack.technoherder.com/input-sanitization/ https://developer.wordpress.org/plugins/security/securing-in... https://stackoverflow.com/questions/129677/how-can-i-sanitiz...
But there are also results where it isn't really clear, or where the only sanitation technique considered is filtering. So I'd say "yeah, it's unclear and poorly defined".
Buuuuut: I still like my definition more, as I have a word for "all techniques that aim to make an input safe for processing" (sanitation/sanitization) while I can still refer to "destructive elimination of substrings" as just "filtering", which is a again different from outright "rejection of input" by using an "allow list" or "deny list". :P
I agree that splitting data and code is the way to go, if that's an option. But I didn't talk about that in the post you're answering to, so I'll ignore that ;-)
This is a form of sanitization.
How are they different?
In 2.16.0 message lookups have been completely removed: https://github.com/apache/logging-log4j2/pull/623
Lookups now only work in configured patterns. Thats IMHO the way it should have been in the first place.
But 2.16 disables JNDI lookups entirely, so that they cannot be triggered via any lookups, including context lookups. But context lookups can still trigger other non-JNDI lookups.
More like blindly trusting that a logging library will just log the strings that you pass to it.
The java ecosystem is full of these abstractions, that are not outright security problems in themselves, but give rise to complex interactions that makes it hard to judge what the implications are.
This particular logging system has been used by millions of developers for the better part of a decade before any one single person realized the actual implications.
It has been used by millions of developers for the better part of a decade before anyone disclosed the implications.
It's not cool, but far less severe than the original issue.
* probably not too hard to come up with a way to break one of the many "grok" pattern regexes https://github.com/logstash-plugins/logstash-patterns-core/b...
Which, if you're still on 1.2.x, also has an RCE against it.
I've heard people talk about this problem with analyzing windows event logs using Java-based software.