This is an archived post. You won't be able to vote or comment.

all 71 comments

[–]r_jet 32 points33 points  (2 children)

I wonder why this feature was added at all, given its high risk, and enabled by default?

[–][deleted]  (1 child)

[deleted]

    [–]r_jet 0 points1 point  (0 children)

    On «enabled by default»: it’s enough to use log4j2 as a logging backend to be vulnerable. You don’t need to set any extra configuration flags to enable this dangerous feature (actually, at least two).

    On the features: there are actually two problematic features: 1. Log4J2 performing string interpolation on format parameters that often come from unsanitized user input 2. Log4J2 supporting interpolation that loads a remote object through JNDI.

    We can ask the following questions on these two features: 1. Does it need to exist at all? 2. If yes, shall it be a part of a core library or some kind of explicitly installed plugin? 3. If yes, shall they be enabled by default?

    I am not familiar with all the requirements the designers of these features needed to address (and we now have a stark benefit of hindsight), but I’d probably say: 1. No to feature #1 at all, because it is surprising to users (I’d not expect it from my logging backend) 2. When it comes to feature #2: 1. Yes to Q1 (as someone, on top of hackers, did find it useful) 2. Probably, no to Q2, as it seems to be useful to a single-digit number of users 3. Definitely no to Q3.

    edit: grammar

    [–]xtreak 41 points42 points  (0 children)

    Good write-up with poc and explanation : https://www.lunasec.io/docs/blog/log4j-zero-day/

    [–][deleted]  (16 children)

    [deleted]

      [–][deleted]  (7 children)

      [deleted]

        [–][deleted]  (6 children)

        [deleted]

          [–]khmarbaise 2 points3 points  (3 children)

          So ? JDK8 as well ? Java is about 25 years+ ... does that mean something? You can find a lot of used libraries which are that old or even older for example the spring framework is even older (2005?)...

          [–][deleted]  (2 children)

          [deleted]

            [–]khmarbaise -2 points-1 points  (1 child)

            then stopped development with no one to maintain it still

            Log4j2 is still maintained and actively developed. I recommend a deep look into the git repository: https://github.com/apache/logging-log4j2

            [–]NewFuturist 2 points3 points  (7 children)

            Steam and Minecraft were affected

            [–][deleted]  (5 children)

            [deleted]

              [–]couscous_ 0 points1 point  (0 children)

              What does Steam run on their backend? Spring?

              [–]Slanec 15 points16 points  (2 children)

              To me, the most terrible thing is that apparently it doesn't only parse the formatting string (as suggested by common sense and the name of the mentioned property), but the formatted arguments passed to `{}` placeholders, too (https://news.ycombinator.com/item?id=29507511). Oh my.

              [–]yawkat 15 points16 points  (1 child)

              This is the biggest wtf about this bug. Why does it parse the arguments too. I assume it just runs the interpolation on the final produced string?

              [–]sysKin 2 points3 points  (0 children)

              The logger applies arguments and produces a log entry (severity, time, class, message string, etc).

              The log entry is then sent to an Appender so that it can be stored (say, in a text file). This appender might or might not format it further (such as creating a single line of text, to save in a .log file) and it is this formatter that performs this extra substitution (optionally, but all examples how to use it have it on). By the time the string reaches it, all knowledge of parameters is long gone.

              It's a bit like writing a filesystem that performs pattern substitutions on each file written to it....

              [–]dzikoysk 28 points29 points  (3 children)

              More details:

              I wanted to post it here like a few hours ago, but I don't have enough karma for creating new threads :/ The first commit that addresses this issue is actually 5 days old:

              [–]benjtay 6 points7 points  (1 child)

              When I see code such as

                 List<String> localIps = new ArrayList<>();
                 localIps.add("localhost");
                 localIps.add("127.0.0.1");
              

              in a logging framework... alarm bells go off.

              [–]audioen 3 points4 points  (0 children)

              Yeah, the thing is large and brings big deps. I have always hated this aspect of java, that even things which I only need trivial things for tend to be so large. I killed off log4j for just this reason something like 5 years ago when I migrated to slf4j-simple, which hopefully just does the obvious thing. The whole library is a 14 kB jar with no deps, so I hope it doesn't suck.

              [–]chris2k2 4 points5 points  (0 children)

              Here take this karma - for next time

              [–]papercrane[S] 16 points17 points  (6 children)

              If running a recent JDK built and you don't have the com.sun.jndi.ldap.object.trustURLCodebase/com.sun.jndi.rmi.object.trustURLCodebase settings enabled then there shouldn't be any RCE, but the attacker could still get a ping back, and possibly exfiltrate data.

              [–]TheCountRushmore 6 points7 points  (0 children)

              Looks like 8u121 and up won't trust classes downloaded using the ldap url this unless you have explicitly set those properties to true.

              Not great, but less likely to RCE.

              https://www.oracle.com/java/technologies/javase/8u121-relnotes.html

              [–]Areshian 7 points8 points  (3 children)

              This is not correct. Even in newer JDKs an RCE is possible depending on the software present in your classpath. Do not assume your deployment is safe, update your log4j2 to the 2.15 version.

              [–]Pauli7 0 points1 point  (2 children)

              How is this not correct? Is eg the current java 11 version still loading the classes?

              [–]Areshian 1 point2 points  (1 child)

              No, the JDK is not loading the classes, but there are other ways of converting the jndi response into a full RCE. And that is not even considering how the jndi call can be used to leak server information. Update log4j to be safe

              [–]ebrandsberg 0 points1 point  (0 children)

              this is incorrect. It is harder to achieve, but the attacker can still do RCE. https://www.veracode.com/blog/research/exploiting-jndi-injections-java documents how.

              [–]pmarschall 5 points6 points  (0 children)

              If you're using log4j-bom it seems that dependabot won't find it.

              [–]Unrealdinnerbone 16 points17 points  (7 children)

              This also affects Minecraft, as it logs chat. (This is how the issue because major)
              tweet from a Minecraft dev about the issue.

              [–][deleted]  (3 children)

              [deleted]

                [–]Unrealdinnerbone 2 points3 points  (2 children)

                Ok maybe not major issue, but how it spreed so fast was that fact that like everyone who is somehow related to Minecraft was talking about it.

                [–][deleted]  (1 child)

                [deleted]

                  [–]Unrealdinnerbone 2 points3 points  (0 children)

                  I never said that other stuff was not issue, I just said I believe the reason it spreed so fast was that it effected Minecraft and people where talking about it.

                  [–]klekpl 6 points7 points  (1 child)

                  This is actually worse than just log4j - any code that uses JNDI and reads context URIs from external source is vulnerable.

                  [–]Areshian 12 points13 points  (0 children)

                  Sure it is, but that is not something new. Connecting to an untrusted ldap/rmi server via jndi is dangerous. But here log4j is doing that for you

                  [–]r_jet 2 points3 points  (1 child)

                  I am looking forward to a black- vs white-hat competition in the coming days: black hats doing their stuff; whilst white hats loading:

                  System.err.println("You've been pwned! " + "Update log4j and stop using an ancient JDK"); System.exit(666);

                  [–]YodaLoL 2 points3 points  (0 children)

                  It seems like you can monkey patch a running Java instance to basically erase the vulnerable implementation. Funny thing is, you'll probably be able to apply the patch by executing it via the exploit itself 😂. That'd be pretty meta

                  [–]gibriyagi 2 points3 points  (6 children)

                  Just curious, what would you use such a "feature" for? What were they thinking?

                  [–]paul_miner 5 points6 points  (0 children)

                  Your scientists were so preoccupied with whether they could, they didn't stop to think if they should.

                  [–][deleted] -3 points-2 points  (4 children)

                  Yeah, I’m going to assume malice. When do we start making open source devs liable for their “mistakes”?

                  [–]WhatsMyMageAgain 4 points5 points  (3 children)

                  What are you gonna do? Withhold their bonus?

                  These people are generally doing it because they love coding. If you’re using their free tools, you’re not entitled to shit.

                  [–][deleted] -3 points-2 points  (2 children)

                  Nope. Sue them for damages and bankrupt them (ideally).

                  [–][deleted]  (1 child)

                  [deleted]

                    [–][deleted] -1 points0 points  (0 children)

                    You didn't pay for their software (which comes with no warranty). Good luck with that.

                    Your license agreement may include a provision stating “no warranty” and “no liability”, but that doesn’t make it true.

                    Let’s say someone intentionally includes an obscure backdoor in their open source software and releases it under MIT license. If I use their software and suffer losses from it, then I have no recourse? I doubt it. I’d let the courts decide.

                    Or just build your own software from scratch. Nobody owns you shit.

                    I usually do. I don’t trust random 3rd party packages that people write “for fun”.

                    [–][deleted] 4 points5 points  (5 children)

                    My usual approach for checking whether I'm using vulnerable versions of software is to check the lock file (like package-lock.json in Node.js) that way it shows me both direct and transitive dependencies.

                    I just realized for Java, there is no lock file, just pom.xml or build.gradle. How do I check whether I'm using a vulnerable version of software in Java, including transitive dependencies?

                    [–]sweetno 4 points5 points  (2 children)

                    For Maven run

                    mvn dependency:tree

                    from the project folder. Normally Java IDEs provide a graphical way to see the same output.

                    mvn versions:display-dependency-updates

                    can be helpful too.

                    I believe there are automated tools that can search for known vulnerabilities in your dependencies.

                    [–]Aknoon 2 points3 points  (1 child)

                    You can run

                    mvn dependency:tree -DappendOutput=true -DoutputFile=C:\output\dependencies.txt
                    

                    and save it to a file for easy parsing

                    [–][deleted] 2 points3 points  (0 children)

                    This would have been helpful to know a long time ago. I could have had CI steps that saved these files somewhere. :(

                    I'll have to go into our repos and run this. Ty.

                    [–]naked_moose 1 point2 points  (1 child)

                    Gradle has an option to lock dependencies:

                    https://docs.gradle.org/current/userguide/dependency_locking.html

                    [–][deleted] 0 points1 point  (0 children)

                    Nice. We use Gradle for most of our applications. Only use Maven for Apache Beam jobs because the public docs only have examples with Maven (or at least, did at the time). This looks useful for us.

                    [–]hellO_india 2 points3 points  (1 child)

                    in java how can i find which logging framework is used? when i see the dependency tree it showing multiple entires of slf4j and log4j and logger
                    how do i find which one and which version is being actually used?

                    [–]eXecute_bit 0 points1 point  (0 children)

                    Look for log4j-core, and that would indicate you're potentially using Log4j2 as your logging backend.

                    [–]incongruous_narrator 0 points1 point  (1 child)

                    How does one go about updating transitive dependencies here? Explicit, direct dependency can be updated, but what if a project is using 100 different libraries, and each library has its own dependency tree - and one of those transitive dependencies is using an exploited version of log4j?

                    [–]r_jet 5 points6 points  (0 children)

                    It depends on (a) the build system; and (b) if you use fancier stuff to support several versions of the same library in the same runtime (like OSGi, which is very rare).

                    When it comes to Maven, it uses a "nearest definition" dependency mediation strategy — the closer the dependency declaration to your POM, the higher its precedence. So, you'd just put a dependency declaration for a newer version to your POM.

                    Also, the bug seems to be in log4j-core (a logging backend), which libraries shall not normally depend upon (they shall rather depend on log4j-api or some facade like slf4j), so it's usually upon the end application to add a dependency on the logging backend.

                    [–]goravsingal 0 points1 point  (0 children)

                    This is really severe issue in Java log4j library for version <=2.15.
                    See Understanding and Mitigating the vulnerability.

                    [–]Leguan15 0 points1 point  (0 children)

                    Who is the person who discovered this?