Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
Java Security

New Zero-Day In the Log4j Java Library Is Already Being Exploited (zdnet.com) 122

A newly discovered zero-day vulnerability in the widely used Java logging library Apache Log4j is easy to exploit and enables attackers to gain full control of affected servers. ZDNet reports: Tracked as CVE-2021-44228, the vulnerability is classed as severe and allows unauthenticated remote code execution as the user running the application utilizes the Java logging library. CERT New Zealand warns that it's already being exploited in the wild. CISA has urged users and administrators to apply the recommended mitigations "immediately" in order to address the critical vulnerabilities. Systems and services that use the Java logging library, Apache Log4j between versions 2.0 and 2.14.1 are all affected, including many services and applications written in Java. The vulnerability was first discovered in Minecraft but researchers warn that cloud applications are also vulnerable. It's also used in enterprise applications and it's likely that many products will be found to be vulnerable as more is learned about the flaw. Slashdot reader alfabravoteam shares an excerpt from a blog post by researchers a LunaSec, warning that "anybody using Apache Struts is likely vulnerable." From the report: Given how ubiquitous this library is, the impact of the exploit (full server control), and how easy it is to exploit, the impact of this vulnerability is quite severe. We're calling it "Log4Shell" for short (CVE-2021-44228 just isn't as memorable). The 0-day was tweeted along with a POC posted on GitHub. [...] This has been published as CVE-2021-44228 now.

Many, many services are vulnerable to this exploit. Cloud services like Steam, Apple iCloud, and apps like Minecraft have already been found to be vulnerable. Anybody using Apache Struts is likely vulnerable. We've seen similar vulnerabilities exploited before in breaches like the 2017 Equifax data breach. Many Open Source projects like the Minecraft server, Paper, have already begun patching their usage of log4j [to log4j-2.15.0-rc1].

This discussion has been archived. No new comments can be posted.

New Zero-Day In the Log4j Java Library Is Already Being Exploited

Comments Filter:
  • Wow good thing (Score:5, Insightful)

    by phantomfive ( 622387 ) on Friday December 10, 2021 @06:01PM (#62067929) Journal

    Good thing they used a memory-protected language like Java so that exploits can't happen. /s

    Let this be a lesson: switching to a "safe" language like Rust won't save you from security vulnerabilities. You still have to write good code.

    • Seat belts are useless, because some people die in car accidents anyway.
    • Re: (Score:2, Funny)

      Who the hell modded this guy down, does the truth hurt that much ?? damn sensitive java-spurting taint monkeys around here...

      • by Arethan ( 223197 )

        No doubt. GP definitely isn't "Flamebait". Whoever did that should man up and post a comment to undo the mod.

        Sometimes pointing out the seemingly obvious and making a statement about it is downright necessary.
        If we don't continue to point out that even "safe" languages can still be dangerous, how are people new to the industry supposed to learn without simply repeating the same mistakes?

      • by piojo ( 995934 )

        I think the GP was modded down because the memory safety of Rust is in a whole other league than that of Java. For instance, getting the last element of a list has a built in bounds check (which must be handled by the developer rather than throwing an exception), and the code that bypasses the bounds check is an obvious anti-pattern and obviously wrong upon reading it. (You need to add code to bypass the bounds check rather than the shorter version having no check.)

        Rust won't save you from logic bugs, but i

        • Memory safety doesn't help when exploits like this are easy to trigger. Seriously, how is it that in this day and age, you can still trigger an exploit by posting a URL in a chatbox?

          No amount of memory safety is helpful when people do stupid things like not sanitizing inputs (and certainly not executing them or following the URL), having defaulted admin passwords or backdoors, and keeping/transferring sensitive data in plaintext.

          Attackers will always go for these easier modes of exploits than trying t
          • These modes of attack are only easier now because the operating system now protects memory-unsafe languages with things like NX pages, address space layout randomization, et cetera. Until then buffer overflows were the easiest thing in the world to exploit.

            Nobody sanitizes their inputs to logging APIs. You want to have the raw data (unless it's sensitive like a password). The primary concern with logs is log forging attacks that allow one to make an untrue claim backed up with fabricated log data.

            Fro

            • These modes of attack are only easier now

              Are you high? It has always been many times easier to find injection attacks, than to craft a very special executable, that you then have to run on the local machine, and hope that it will get the right conditions to trigger it. And it has always been much easier and more fruitful to find passwords stored in plaintext on some internet exposed server because some negligent "security" person didn't secure it.

              • I don't think you understand how remote buffer overflow attacks work. They are the same as an injection attack. A network service is given data that triggers a buffer overflow and executes the payload. That give you full control at the same privilege level as the service is running. An injection attack only gives you limited control. It's also easier to execute buffer overflow attacks because you do them in two stages. First you find the buffer overflow and then you develop the payload. With injectio
        • What are you talking about? Do you think Java or Javascript or Python allow you to do an out-of-bounds array access? How is Rust any better at this than those languages?

          • by piojo ( 995934 )

            Happy to try to explain. Say you are building a nested list, a list of groups. You have a loop and are deciding whether or not to add the element to a new list or to the existing top list. In a traditional language, you do this with a bounds check:

            if (lists.Length > 0 && lists.Last().Length + 1 ` can't be treated as `int` in most cases). Mutability is encoded in the type of reference. When possible, bounds checks and other error conditions are also encoded in the type information so they must be

            • by piojo ( 995934 )

              Sorry part of the comment was lost due to slashdot markup parsing. I'm not sure all that was lost, but part of what I was saying is that like `Nullable[int]` can't be treated as `int` in C#, `Option[T]` or `Result[T, Err]` can't be treated as `T` in Rust.

            • You have a loop and are deciding whether or not to add the element to a new list or to the existing top list.

              I don't understand why anyone would want to do this. If you have a list of groups that's one thing, but usually membership in a group is decided by some logical element, not by the max size of the group.

              if (lists.Length > 0 && lists.Last().Length + 1

              I also don't understand why anyone would do this.

              Finally I don't see how Rust makes this safer than Java/Javascript/Python. What error would you expect to see in Java?

              • by piojo ( 995934 )

                It's simplified code from duplicate checking. Groups are files that are potentially duplicates, but there is a length bound because of memory. And again, sorry the code and comments got mangled. I'll use code tags next time, but it can't be edited or quoted to be fixed--Slashdot ate the original form input.

                Finally I don't see how Rust makes this safer than Java/Javascript/Python. What error would you expect to see in Java?

                You have it backwards. It's Rust that gives errors.

                lists.last().push(element)

                would give an error about `lists.last()` not being mutable, and also not having a `push` method (since it's an `Option` of a da

                • ok, how is this safer than Java or Javascript or Python?

                  • by piojo ( 995934 )

                    The Java/Python error happens at runtime if the list is empty. In these mainstream languages, it's natural to sometimes forget to check bounds/null and handle that case. Whereas in Rust you have to add extra function calls to skip the checks.

                    • by raynet ( 51803 )

                      How can Rust know at compile time that the list is empty?

                    • by piojo ( 995934 )

                      It doesn't, but the most typical API to get the first or last element (or to pop off an element) returns an Option[T] instead of the underlying type. And to extract a value from an Option, you either need to write opt.unwrap() (which is a well known naughty function) or do error checking. The value is extracted as part of the error checking syntax--it's like an `if` or `switch` statement that covers the possible values (Ok/Err, or Some/None) and can execute logic on the contained value or return it.

                      The deve

                  • by piojo ( 995934 )

                    Also there can be runtime concurrent modification errors. Those don't typically happen in Rust due to the compiler being a harsh mistress about when objects are allowed to be mutable.

                    • These don't happen in Java either. At least not if you use the built-in collections classes. I mean yeah I guess if you rolled your own. Java is mature and so are the collections. They have well defined behaviors. Maybe there are things the compiler can't catch that result in runtime errors (which could be DoS). It's great to have a language that improves the ability of compile-time checks. And I would want to use it since that would increase productivity and decrease bugs. But its not clear that a c
                    • by piojo ( 995934 )

                      I can still find very recent blogs that talk about Java concurrent modification exceptions when you modify a data structure during iteration, for example: https://www.baeldung.com/java-... [baeldung.com]

                      In every mature language I've used, the "well defined behavior" is to throw a runtime exception in this case. It's not usually a problem, but (just like forgetting a bounds check), it's normal to sometimes forget to either copy the list or make a separate list of data to be removed. (This applies to cases where you wouldn'

                    • That's the point! If you concurrently modify when you shouldn't, there are built-in checks for the purpose of ensuring that it doesn't become an exploitable race condition. Yes it would be better if the compiler enforced this. And in some cases it can. If all of the code is in the same thread. But no compiler can completely enforce thread safety. Hence the checks!
                    • by piojo ( 995934 )

                      Okay. My point was that when I said concurrent modification exceptions don't happen in rust, I meant they really don't happen.

                      The constraints of the statically guaranteed checks are sometimes pretty annoying, though. I find most of it pretty manageable, but lifetimes are hard. (Imagine you had to name the scope in which a reference is valid. And imagine you also have to name the scopes of validity of generic type names. It's a bitch, and the compiler can't tell you when the problem is solvable or indicates

            • There's another issue as well. Anyone can look at an expression like " (lists.Length > 0 && lists.Last().Length + 1" and see what it's doing. However, something like "match lists.last_mut() { Some(last) if last.len() + 1 last.push(elem), _ => lists.push(vec![elem]), }" is best understood when viewed upside-down in a mirror, possibly while stoned.

              Now imagine a 250 kloc program written like that, and try and audit it for errors and vulnerabilities...

              • by piojo ( 995934 )

                I agree, actually. It's a real trap for newbies (myself included) to write code that makes the compiler happy (all types, mutability, error handling statically correct) but is too hard to read.

      • by Luthair ( 847766 )
        He's either a troll, or he doesn't know enough about programming to comment.
      • The OP is ridiculous but not flamebait. Memory-protected languages have reduced the incidence and severity of security defects but of course they aren't perfect. "Good thing they got the vaccine so they can't get COVID." It's the exact same fallacy as the anti-vaxxers are putting forward. It doesn't work there and it doesn't work here. Using a safe language, where appropriate, is a smart move that results in better software but doesn't eliminate the need for comprehensive security programs and controls
    • Good thing they used a memory-protected language like Java so that exploits can't happen. /s

      Let this be a lesson: switching to a "safe" language like Rust won't save you from security vulnerabilities. You still have to write good code.

      A down mod for this comment is completely uncalled for.

      • Not even for the strawman argument?

        The only claims I've seen of security vulnerabilities being impossible in Rust are from posts like the GP trying to point out how obviously stupid such claims are.

        I mean, yeah, those claims are obviously stupid, but who's the one posting them?

        • This is the type of comment where responding is better than downmods. I don't agree with the comment and it may have been intentionally provocative. But it also hints at a truth that language selection is only one small part of a comprehensive security program and that security is often an afterthought until it isn't. But it's not clear that the comment was a troll or flamebait and better to post meaningful replies.
    • In fairness (and I share the dislike of Rust for its community attitude), the log4j code in question doesn't look like bad code. It is the standard case of wanting to provide a feature and not realizing that the feature could be used as a backdoor.

      You can even argue it is good code, it implements exactly what the interface requires, no more, no less. It is the _interface_, both explicit in code and implicit in formatting, that is bad, or not thought out carefully. I cannot see how this kind of thing could b

      • You should know what the libraries you are using do before calling them.

        • The interface doesn't say; if the documentation does, it's probably buried in it. Even if you wrote the library you may forget about that part -- and I have no doubt that the log4j2 author probably also used it an an unsafe way.

          There is just no way that a reasonable person can be suspicious of calling log.info( myString ), even if he is a security freak.

  • Nasty bug (Score:4, Insightful)

    by peppepz ( 1311345 ) on Friday December 10, 2021 @06:41PM (#62068075)
    This exploit seems extremely serious. But at least, in order to be vulnerable, besides the buggy log4j, you also need to be using a vulnerable JRE [lunasec.io], that would accept Java class bytecode over LDAP:

    JDK versions greater than 6u211, 7u201, 8u191, and 11.0.1 are not affected by the LDAP attack vector. In these versions com sun jndi ldap object trustURLCodebase is set to false meaning JNDI cannot load remote code using LDAP.

    It's surprising to me that important web-facing software, including parts of Apple's cloud services, is still running Java versions that haven't been patched in three years (those versions are from 2018).

    • It's surprising to me that important web-facing software, including parts of Apple's cloud services, is still running Java versions that haven't been patched in three years
      That is not surprising at all. That is very common.

      • by kriston ( 7886 )

        You can blame Oracle's Java license fiasco over the past five years. Until recently, nobody could be completely sure if they were legally allowed to upgrade past JRE 8.

        • Hu?

          Never heard about OpenJDK?

          Oracles Java is nothing different than a rebundeled/rebranded OpenJDK anyway.

    • It's easy to mitigate. Set 'log4j2.formatMsgNoLookups' to 'true' and you're done.
      • If their system is already infiltrated, nothing stopping attackers from setting to false again.
        • This was an RCE but it would only lead to infiltration if one could use the RCE to escape the Java sandbox. We haven't heard of that happening. Setting the value and restarting will close the exploit unless there has been further compromise. If they are using older JREs that's certainly possible but that would require yet another attack vector.
          • If you can RCE, then it's only a matter of time to find ways to escape the sandbox.

            You can already escape the Javascript sandbox with an RCE.
            • Yes which is the "another attack vector" that I pointed out. I'm not sure how hard Java sandbox escapes are these days.
      • by butlerm ( 3112 )

        It is not easy to mitigate if you actually need the feature that setting disables. Then you are in trouble. On the other hand, it is hard for me to understand how that particular feature could come into widespread use with that api without a healthy percentage of the developer population realizing it was inherently vulnerable, defective by design, and the next closest thing to software engineering malpractice.

    • > It's surprising to me that important web-facing software, including parts of Apple's cloud services, is still running Java versions that haven't been patched in three years (those versions are from 2018).

      Not very familiar with enterprise software, are you?

      I had people asking if using log4j 1 should be considered a vulnerability and we patiently explained that it went EOL many years ago and has its own RCEs, so yes, it is a vulnerability.

      • If we were talking about Uncle Joe's e-commerce web site then no, I wouldn't be surprised, but... the servers that manage the iphones' change of name? Wow.
        • The bigger the company, the harder (and more expensive) it tends to be for them to make changes. They have software integrated with all the other software and just testing changes is non-trivial, let alone making plans to back everything out.

          As a consequence, they have a hard time doing frequent updates of their software and the hardest to change bits tend to get very, very out of date. It's not uncommon for larger enterprises to find themselves using stuff that went EOL years ago that they just haven't g

          • by mspohr ( 589790 )

            Interesting that Tesla has a completely automated test suite so that they can make hardware and software changes and have them tested immediately. Every car runs the test suite.
            Tesla makes 20-30 changes to their hardware and software every week. It's one of the traits that keeps them far ahead.
            Maybe other companies should look into doing something similar to avoid being stuck with old, buggy code.
            Here's an interview which explains their process:
            https://youtu.be/Pk4Ygmd8fLc [youtu.be]

    • This exploit seems extremely serious. But at least, in order to be vulnerable, besides the buggy log4j, you also need to be using a vulnerable JRE [lunasec.io], that would accept Java class bytecode over LDAP:

      JDK versions greater than 6u211, 7u201, 8u191, and 11.0.1 are not affected by the LDAP attack vector. In these versions com sun jndi ldap object trustURLCodebase is set to false meaning JNDI cannot load remote code using LDAP.

      It's surprising to me that important web-facing software, including parts of Apple's cloud services, is still running Java versions that haven't been patched in three years (those versions are from 2018).

      It's not really that surprising. Something previously considered not to have any vulnerability or known exploits that isn't causing any problems isn't going to get touched too often. Updating to newer versions has a tendency to add bugs or break something else and it's hard to get management to agree to spend time to fix everything and ensure the system isn't going to have any unintended side effects.

      We've still got loads of ancient code in use every day. There's more than we can reasonably maintain and

  • by Somervillain ( 4719341 ) on Friday December 10, 2021 @07:48PM (#62068247)
    Apparently, the native solution is garbage, so we need a million libraries to log debugging statements, include slf4j...a weird abstraction for all those people who love switching between log4j vs log4j2 vs logback...and every 5 years, the logging framework du jour has to change.

    99% any time you hear someone complain about Java, they're a clueless moron who is complaining about a bad applet or JWT/Swing experience they had 20 years ago...but sometimes Java does give them a legitimate reason to complain, and the logging situation is definitely one of those.

    Every app logs. I don't know why they haven't introduced a good solution into the JDK, or the very least, the JEE. I don't know why the logging API wasn't solved in the 90s.
    • I don't know why they haven't introduced a good solution into the JDK, or the very least, the JEE.
      There is one since Java 8.
      But developers like to stick to old stuff.

      • Everyone used Log4J. So you might expect that to be included as standard, or something very compatible.

        But Java introduced something completely different.

        As to how logging software could introduce a security flaw, that would be interesting to know. Is Log4J reaching out into the web? It should be a simple log library, that just writes to log files...

        • by bsolar ( 1176767 )

          As to how logging software could introduce a security flaw, that would be interesting to know. Is Log4J reaching out into the web? It should be a simple log library, that just writes to log files...

          Log4j has mechanisms to lookup information from various sources [apache.org], including JNDI. A JNDI resource can reside in a LDAP server, which means looking up that resource effectively means accessing that server.

          As far as I understand the exploit requires the logging to resolve a LDAP resource via JNDI against an hostile LDAP server and is typically exploited when the logging includes user-controlled input which can be abused to trigger such lookup against a LDAP server of choice.

          • I do not understand. We control the config.

            What we do not want happening is the lookup being triggered by a log message, whose content comes from elsewhere. If so, we need to log4j-escape them.

            And I do not want to wait for the next security hole to be discovered. I want no clever processing at all.

    • Apparently, the native solution is garbage, so we need a million libraries to log debugging statements,

      Well the JDK devs don't have a UI to do a UI refresh on like Microsoft, Mozilla, etc, so they need something else to fuck with all the time. Looks like their one is logging frameworks...

    • by kriston ( 7886 )

      And then C Sharpers have log4net. Wonder if this affects them?

  • People are using frameworks everywhere now. Sure logging might be a good reason to use one. But really what happens is someone wants to use some functionality and instead of coding it, or instead of the language having a more granular library to load, they load one of the many frameworks out there. So now there are more places where potential bugs may be found to be exploited, even if the app/service isn't even using that part of the framework. And since many developers around the world use frameworks simil

    • Re: (Score:2, Insightful)

      by Anonymous Coward

      So little on writing code that even if you want to look for security issues in your code, you don't have time to, or maybe can't even learn how because you're forced to learn whatever CICD tool of the day is out there rather than best coding security practices.

      Ironically given the rest of your post, this is one of the best arguments FOR using a library.

      Statistically, the people focusing on one smaller function and doing so for such a long time, tends to result in those people becoming the experts you don't have time to even start learning.
      Far more often than not, this results in the library doing the task leaps and bounds better than you could yourself. At least not without spending dozens of years of your life working on.

      Another benefit, more for libraries that

      • by raymorris ( 2726007 ) on Friday December 10, 2021 @10:29PM (#62068541) Journal

        Here's an important bit from the OP:

        --
        When you have frameworks everywhere that unnecessary huge increase in size of your deployed code can harbour dangers.
        --

        Unnecessarily loading a huge amount of code you're not using is bad. The only code that's definitely safe is code that isn't there. So using a million-line framework for an 8-line function is a bad idea.

        On the other hand, small, focused libraries that are widely used and tested often have very well-written code.

        One example we've all probably seen is someone loads jQuery for a page with one line of JavaScript. One friggin line.

        One the other hand, rolling your own encryption code is really, really bad idea. There are times to use a library, times not to, and once on a while it even makes sense to use a huge framework.

        • One the other hand, rolling your own encryption code is really, really bad idea.

          Depends on if you're a better programmer than the people who wrote the already existing library. It's possible you are.

          • > > One the other hand, rolling your own encryption code is really, really bad idea.

            > Depends on if you're a better programmer than the people who wrote the already existing library. It's possible you are.

            That's actually a really good example of someone who shouldn't! :)
            If you think being a better programmer is the criterion, you're so far off base that not only should you not write your encryption algorithm, it's questionable whether you're even really qualified to be *using* encryption in softwar

            • Even if you are a better programmer, mature code that's had lots of people test it will still be better than what you get if you start fresh. Especially, as you said, if it's a domain you don't know as well.
            • Yeah you're right - after 25 years of active study it's entirely possible that I am a better *programmer* than Schneier, Lucks and Ferguson. There's a zero percent chance that I'm a better *cryptographer* than any of them, much less all of them put together.

              You don't need to be a better cryptographer. You need to understand the encryption algorithm you are trying to implement.

              Most security bugs in the common encryption libraries are implementation details, not algorithm problems.

              There are about a dozen people in the world who are qualified to write encryption algorithms, and they work in *teams*. They all know they aren't qualified to do it alone. Rather they work in teams of 2-5.

              Daniel Bernstein could do it.

              • Oh yes, DOCTOR Bernstein, PhD can do anything better than anyone, mostly by doing exactly the opposite of what everyone else does, because everyone else has *learned* from the past. :)

                Geez that dude was a PITA to work with.

                • Geez that dude was a PITA to work with.

                  I'm sure he is, he has the "90s nerd" arrogance. He's somewhat better than Theo in terms of interpersonal skills. I'll bet you have some good stories.

                  But still, wouldn't you say that NACL crypto library is rather good?

                  • I haven't analyzed NaCL sufficiently to comment on if it's good.
                    I can mention that it's a collaboration between three primary authors and numerous reviewers. The core is DJB with Tanja Lange who chair of the cryptography group at one university, and Peter Schwabe who is a tenured professor at the Max-Planck Institute for Security and Privacy and a part-time professor for cryptographic engineering at Radboud University.

                    So the initial core is two top cryptographers plus DJB, reviewed by Alejandro Hevia and Gr

        • You picked up what I was laying down.

        • Java has a module system to partly mitigate this so you don't have to take the entirety of a framework. But log4j isn't that big.
    • Learning CICD and the concepts behind it takes less than a week. Once it is in place, pretty much all your projects should follow the same patterns so I don't know why you are complaining about it wasting your time.

      Learning security code best practices should be done continuously and applied to each project you work on, it's part of the job. Software development doesn't just encompass the actual coding...security best practices also applies to CICD, data access, cloud architecture, mesh, containers, etc
      • Learning CICD and the concepts behind it takes less than a week. Once it is in place, pretty much all your projects should follow the same patterns so I don't know why you are complaining about it wasting your time.

        Indeed, the biggest difficulty with continuous integration is not learning it, but keeping it simple. Build/deploy scripts get complex faster than any other type of code. You need to be obsessive about not letting it get out of hand.

    • People are using frameworks everywhere now. Sure logging might be a good reason to use one. But really what happens is someone wants to use some functionality and instead of coding it, or instead of the language having a more granular library to load, they load one of the many frameworks out there. So now there are more places where potential bugs may be found to be exploited, even if the app/service isn't even using that part of the framework. And since many developers around the world use frameworks similarly, there are many potential places that might be exploited unnecessarily. Massive single point of failure. When you have frameworks everywhere that unnecessary huge increase in size of your deployed code can harbour dangers. Too many frameworks. Never mind that it makes being a programmer a pain in the ass because you have to learn more and more non-coding things so that you spend most of your time configuring frameworks a devops nightmares. So little on writing code that even if you want to look for security issues in your code, you don't have time to, or maybe can't even learn how because you're forced to learn whatever CICD tool of the day is out there rather than best coding security practices.

      So you exclusively write assembly I take it? That way you never have to rely on anyone else's code. Oh but wait, those hardware instructions you're using are the same ones a billion other processors out there are using. They can and do have security vulnerabilities. You better start building your own chips too then, just to be safe.

"A mind is a terrible thing to have leaking out your ears." -- The League of Sadistic Telepaths

Working...