from Hacker News

Spring Core on JDK9 is vulnerable to remote code execution

by groundshark on 3/30/22, 8:26 PM with 70 comments

  • by WatchDog on 3/31/22, 1:04 AM

    There is a lot of bad information out there about this issue.

    What I have gathered so far, is that this is actually a real problem, but it may not affect most configurations.

    This[0] seems to be the original vulnerability analysis, and this is the example vulnerable app[1].

    The main issue seems to be, that since java 9, WebDataBinder can be abused to access the classloader via the "class.module.classloader", you might think that "class.classloader" would work, but it's explicitly filtered out[2], it seems they need to add some filtering for module, as well.

    The proof of concept, then access the "AccessLogValve" class via "class.classLoader.resources.context.parent.pipeline.first", which is only accessible if the application is running using a "WeappClassLoaderBase", it then configures the logger, to output an arbitrary JSP file to the webapp root directory, which can then be used to get a shell.

    It looks like this issue is only exploitable if your app is deployed as a war file.

    [0]: https://github.com/TheGejr/SpringShell/blob/master/Vulnerabi...

    [1]: https://github.com/fengguangbin/spring-rce-war

    [2]: https://github.com/spring-projects/spring-framework/blob/mai...

  • by invokestatic on 3/30/22, 10:53 PM

    I am still deeply skeptical that this exploit really exists, or if it does, it is extremely exaggerated. I can’t really articulate the reasons why. Part of it is the fact that a lot of the people reporting on it self-admit that they are unfamiliar with Java and Spring. One “PoC” repo I’ve seen is just simple API misuse. API misuse is a CVE in the application that does the misusing, NOT the library that is misused (in this case spring).

    Something else is that very soon after there was a /hint/ of a log4j exploit, we saw rapid and evolving exploitation in the wild. We have nothing like that happening now, since this news first broke, what, 12 hours ago?

    Then there’s also the suspicion where I feel the LunaSec people, one of the first groups to report on this, are desperately trying to re-catch the fire they caught when they first reported log4j. I’m sure that was amazing for marketing their company. Problem is, I think reporting on this before there is really indication of a real issue reduces the credibility of them as competent security researchers.

    Of course, I may come back to eat my words.

  • by alipitch on 4/13/22, 5:39 AM

    Are there any data binding libraries (deserialization, marshaling, pickling libraries) that do not have the class of weaknesses as the two CVEs (CVE-2022-22965, CVE-2010-1622)?

    My understanding is as follows.

    - Spring uses WebDataBinder [0]. -> CVEs: CVE-2022-22965 (Spring4Shell), CVE-2010-1622 -> CVE Fixes: First deny-list approach (2010), then partial allow-list approach (2022)

    - Struts uses OGNL. -> CVEs: CVE-2017-5638 (Equifax breach), and others -> CVE Fixes: deny-list approach (-2017-)

    If there are any for Java, can they be used with Spring Boot (Spring Framework)? Maybe there are some for in another programming language?

    [0] https://docs.spring.io/spring-framework/docs/current/javadoc... > Special DataBinder for data binding from web request parameters to JavaBean objects.

  • by Copenjin on 3/31/22, 10:32 AM

    Official announcement, a better remediation is proposed: https://spring.io/blog/2022/03/31/spring-framework-rce-early...

    A new spring release should come out today.

  • by toyg on 3/31/22, 7:00 AM

    Title should be fixed to say 9+ (as in the original source). I initially discounted the issue because v9 was a somewhat-experimental release that very few people ever ran in production; but later versions were mainstream, and if they are all vulnerable, then this is a major problem.
  • by trollied on 3/31/22, 11:57 AM

    Spring have blogged about it. Releases are on the way: https://spring.io/blog/2022/03/31/spring-framework-rce-early...
  • by hrpnk on 3/31/22, 11:19 AM

    https://spring.io/blog/2022/03/31/spring-framework-rce-early...

    "[11:59 BST] Spring Framework versions 5.3.18 and 5.2.20, which address the vulnerability, are now available on Maven Central. The release process for Spring Boot is in progress, but applications can already upgrade their Spring Framework version independently in order to be protected."

  • by freeqaz on 3/30/22, 10:59 PM

    (Author that named "Log4Shell" here)

    FYI, this is confusing because there are 2 different RCEs that have been published within the last 24 hours. One has a CVE and the other doesn't.

    OP's post by Praetorian is discussing the RCE dubbed "Spring4Shell".

    It's the RCE without a CVE yet, hence the name, and it affects Spring Core. It's likely fairly widespread/severe, but the "mitigating details" are still unknown.

    That said, it's very similar to the Apache Struts vuln that popped EquiFax a few years ago. (a Class Loader Manipulation exploit) So there is already some tooling available to weaponize it.

    The other RCE affects Spring Cloud Function and has been given CVE-2022-22963.

    We wrote a post[0] with info on both CVEs that references this Praetorian post under the "Remediation" section. We also added more information about the exploit scenarios to help push the ball forward for determining how widely exploitable this is going to be.

    (There is a 3rd possible one too, but it's still unconfirmed.)

    Basically, the authors of Spring Core tweeted[1] that there wasn't a vuln and that has added to the chaos of this. There is a vuln here. It's not as bad as Log4Shell, but it's still bad and likely widely exploitable given how popular Spring Core is and how some Java devs[2] have confirmed that the exploitable configuration is a "common pattern" in real-world usage.

    With the vuln there are more steps required for exploitation. That means kids on Minecraft won't be griefing each other with it, but that won't stop the blackhats from weaponizing this quickly. After all, this is a very similar attack to previous ones in Struts[3].

    So if you're using Spring Core or Spring Cloud Function, it's a good idea to stay up-to-date on this stuff because it's moving pretty quick. If you already looked earlier this morning, a lot has changed (like this Praetorian post).

    It'll be a fun weekend for security teams everywhere!

    0: https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/

    1: https://twitter.com/hacksilon/status/1509117953064812547

    2: https://twitter.com/pwntester/status/1509298152691671046

    3: https://www.exploit-db.com/exploits/33142

  • by olliej on 3/30/22, 10:37 PM

    Looks like another "I'm in a 'safe' language, so can do unsafe things" crossed with the standard object deserialization error of default allowing any class to be instantiated.

    The temporary fix that they list seems to imply that the current APIs don't allow specifying a finite list of allowed classes?

  • by tauwauwau on 3/31/22, 3:40 AM

    Not sure why it's tagged JDK9+, but 'class' attribute is accessible on org.springframework.beans.BeanWrapperImpl.getLocalPropertyHandler() in JDK 8 also. It probably doesn't matter which JDK is being used, as long as this spring-beans dependency is used.

    Whether logging JSP exploit in JDK 8 or lower can be used is another question. However, since 'class' is accessible via request parameter, it's already bad and there will probably be some ways to exploiting it. It doesn't matter whether the request is GET or POST, as long as mapped controller method uses a non-primitive request object, 'class' can be accessed. 'class.module' attribute is accessible from Java 9 and above, I tested on Java 11 and can access 'class.module'. Sample code that I used to test this with JDK 8 is below. I just tested whether 'class' attribute can be accessed via request parameter.

    curl -X POST localhost:8080/test?class.modifiers=Hello

    package com.test;

        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.web.bind.annotation.PostMapping;
        import org.springframework.web.bind.annotation.RestController;
    
        @SpringBootApplication
        public class Spring4ShellTestApplication {
    
        public static void main(String[] args) {
          SpringApplication.run(Spring4ShellTestApplication.class, args);
         }
    
        }
        @RestController
        class TestController {
    
        @PostMapping("/test")
         public String test(TestOuterRequest request) {
    
          String message = "Inner request is null";
    
          if (request.getInnerRequest() != null) {
           message = "your message was: " + request.getInnerRequest().getMessage();
          }
    
          System.out.println(message);
    
          return message;
         }
        }
    
        class TestOuterRequest {
         private TestInnerRequest innerRequest;
    
        public TestInnerRequest getInnerRequest() {
          return innerRequest;
         }
    
        public void setInnerRequest(TestInnerRequest innerRequest) {
          this.innerRequest = innerRequest;
         }
        }
    
        class TestInnerRequest {
         private String message;
    
        public String getMessage() {
          return message;
         }
    
        public void setMessage(String message) {
          this.message = message;
         }
        }
    
    Finally here are the attributes that're exposed on 'class' as accessible properties in JDK 8 (JDK9+ adds 'module' on top of all these)

        annotatedInterfaces
        annotatedSuperclass
        annotation
        annotations
        anonymousClass
        array
        canonicalName
        class
        classes
        componentType
        constructors
        declaredAnnotations
        declaredClasses
        declaredConstructors
        declaredFields
        declaredMethods
        declaringClass
        enclosingClass
        enclosingConstructor
        enclosingMethod
        enum
        enumConstants
        fields
        genericInterfaces
        genericSuperclass
        interface
        interfaces
        localClass
        memberClass
        methods
        modifiers
        name
        package
        primitive
        signers
        simpleName
        superclass
        synthetic
        typeName
        typeParameters
  • by skered on 3/30/22, 10:52 PM

    JDK9+? Not just 9.
  • by scanr on 3/30/22, 10:41 PM

    “This vulnerability allows an unauthenticated attacker to execute arbitrary code on the target system.”.

    Interesting that the CVE has been around for so long.

  • by groundshark on 3/30/22, 8:26 PM

    Possible 0-day RCE impacting Spring applications.
  • by mbfg on 3/31/22, 12:40 AM

    Fortunately very few companies of any size use jdk9+