| The method responsible for variable substitution is here [1]. There are other lookup mechanisms, (didn't check them all) but they only retrieve environment/static values (this one [2] for example retrieves kubernetes attributes). I think the jndi one is the only one that load and execute code. Edit : I think my understanding of the docs is incorrect so ignore the next paragraph From the documentation [3], I have the impression that these variables should be evaluated only when loading the pattern layout configuration. But in reality they are also evaluated when formatting the final log message (log.info(...)). I agree that the input should be sanitized but only if the formatting behavior is a bug and was not intentional. One possible explanation for the current situation, is that developers assumed that all lookup mechanism will retrieve only static values (env variables for example). And then another dev introduced the jndi lookup which execute code, but no one noticed the impact on the already existing behavior (evaluation variable when formatting the final msg). Edit 1: https://github.com/apache/logging-log4j2/blob/9df31f73b62ba2... 2: https://github.com/apache/logging-log4j2/blob/c2b07e37995004... 3: https://logging.apache.org/log4j/2.x/manual/lookups.html |
Non-pattern arguments should not do any substitution, because otherwise developers have to jump through hoops to output strings verbatim. You don’t want "Invalid identifier: '${<some valid log4j syntax>}'" to be turned into "Invalid identifier: '<the log4j replacement>'" when the actual invalid identifier (e.g. from user input) was the "${…}" syntax. I’m surprised that log4j behaves that way still after two decades.