spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.38k stars 38.04k forks source link

Sonatype vulnerability CVE-2016-1000027 in Spring-web project #24434

Closed gauravdeshmukh612 closed 4 years ago

gauravdeshmukh612 commented 4 years ago

Affects: \5.2.3.RELEASE

Issue Title : Sonartype vulnerability CVE-2016-1000027 in Spring-web project

Description Description from CVE Pivotal Spring Framework 4.1.4 suffers from a potential remote code execution (RCE) issue if used for Java deserialization of untrusted data. Depending on how the library is implemented within a product, this issue may or not occur, and authentication may be required. Explanation The org.springframework:spring-web package is vulnerable to deserialization of untrusted data leading to Remote Code Execution (RCE). The readRemoteInvocation method in HttpInvokerServiceExporter.class does not properly verify or restrict untrusted objects prior to deserializing them. An attacker can exploit this vulnerability by sending malicious requests containing crafted objects, which when deserialized, execute arbitrary code on the vulnerable system.

NOTE: This vulnerability is related to a previously reported deserialization vulnerability (CVE-2011-2894) within the package, impacting a different class.

Detection The application is vulnerable by using this component under specific scenarios as listed out in the advisory.

Reference: https://www.tenable.com/security/research/tra-2016-20

Recommendation There is no non-vulnerable upgrade path for this component/package. We recommend investigating alternative components or a potential mitigating control.

A warning has been provided in the official Javadocs of the HttpInvokerServiceExporter class:

"WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: Manipulated input streams could lead to unwanted code execution on the server during the deserialization step. As a consequence, do not expose HTTP invoker endpoints to untrusted clients but rather just between your own services. In general, we strongly recommend any other message format (e.g. JSON) instead."

The developer's general advice also states: "Do not use Java serialization for external endpoints, in particular not for unauthorized ones. HTTP invoker is not a well-kept secret (or an "oversight") but rather the typical case of how a Spring application would expose serialization endpoints to begin with... he has a point that we should make this case all across our documentation, including the javadoc. But I don't really see a CVE case here, just a documentation improvement.

Pivoltal will enhance their documentation for the 4.2.6 and 3.2.17 releases."

Reference: https://www.tenable.com/security/research/tra-2016-20

Root Cause spring-web-5.2.3.RELEASE.jar <= org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.class : [2.5.1,) Advisories Third Party: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-1000027 Third Party: https://www.tenable.com/security/research/tra-2016-20 CVSS Details CVE CVSS 3: 9.8 CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

YSavanier commented 1 year ago

Great attempt to get everyone to update to Java 17 may I add, that's not really the same as a dependency version change ^^;

As it is indeed a natural thing to update one's JDK version in due time, keep in mind all organisations can't keep up with the version unroll, and asking everyone to change their JVM running on their infrastructure servers OS that might not have it in their package repository cause it was released just a year ago, all just because there is a CVE in a library which will not be adressed by the editor isn't easy to accept.

Working in such environment I should say this is a dead end here, our security department doesn't accept our argument about the CVE being on a class that we don't use and order us to update the dependency (which we can't cause our system department hasn't migrated their redhat version to one that propose the jdk17 yet and refuse to install anything outside it) or remove it without delay (which we can't cause, well... that one is obvious ^^;).

Soooo as it is the only CVE remaining on ours applications and with a critical 9.8 score, I might simply add that's a first time here not being able to mitigate it in any way, not because the library is too old or doesn't have any active maintainer, but only because of pure dogmatism about what a minor version release can or should be able to adress concerning security alerts.

Cheers,

act-amirsky commented 1 year ago

I have been maintaining a long and friendly discussion with @bclozel on this topic and I can see the perspective on both sides. One core issue is that HTTP Invoker is essentially deprecated but "fixing" it is by removing - which I can understand is usually the prerogative of a major release and is what Spring 6 effectively did. The concern on Spring 5 is that removing breaks backward compatibility and API for whoever on the planet (and there are a lot of Spring adoptions) happened to be using this feature.

Let me put a toe into the discussion a last, last time to offer a possible way out here. I will duck and cover after suggesting.

What if the Spring project did not remove the HTTP Invoker - but instead added a blocking control that disables the functionality. It will be disabled by default and can be re-enabled with a one-line property flag for those few who still use HTTP Invoker. I am surmising the noise of the 9.8 CVE is much greater than the possible noise of needing to add a flag to restore deprecated functionality.

Hopefully, the fact that the library by default does not expose the vulnerability would be enough to close the CVE or at least greatly reduce its CVSS score?

bclozel commented 1 year ago

@act-amirsky as you've seen in https://github.com/spring-projects/spring-framework/issues/24434#issuecomment-1317007089, at this point it's not even about whether there's an actual security issue but this entry acts as "relevant information" for developers. Of course, CVE entries are not considered like that by our industry and this is causing the current discussion.

What if the Spring project did not remove the HTTP Invoker - but instead added a blocking control that disables the functionality. It will be disabled by default and can be re-enabled with a one-line property flag for those few who still use HTTP Invoker

The feature itself has always been opt-in, has come with a strong warning for a very long time and has been formally deprecated since 5.3. We've made that point already and this wasn't enough to get that entry suppressed. Adding another opt-in flag is not likely to change anything there unfortunately.

As for the 9.8 score, let me underline again that this was never published by MITRE on the official entry and that this was contributed by NVD independently. We could of course challenge this score, but I don't think that the CVSS score includes whether it requires knowledge and an informed decision from the developer to be exposed to this risk.

Thanks for keeping the discussion constructive and understanding our perspective @act-amirsky.

Jos31fr commented 1 year ago

@bclozel

As for the 9.8 score, let me underline again that this was never published by MITRE on the official entry and that this was contributed by NVD independently. We could of course challenge this score, but I don't think that the CVSS score includes whether it requires knowledge and an informed decision from the developer to be exposed to this risk.

I think it is taken in account, otherwise any java application will be considered at risk due to reflect possiblities.... If this feature is opt-in, the CVSS score should not be 9.8

The main problem is that CVSS score take into account damage but not potential occurence. If we only take damage into account we should all live in a anti nuclear bunker...

bclozel commented 1 year ago

@Jos31fr Feel free to suggest an alternate CVSS score using the generator: https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator

dkykuta commented 1 year ago

With all due respect, may I ask how can the version 5.3 be supported until 2024 if this 9.8 scores makes it unusable for some (maybe most?) of us? What is the plan here?

bclozel commented 1 year ago

@dkykuta we've challenged this report and still believe it is invalid. By the same logic, how can anyone be using Java in production when Java deserialization from untrusted sources is very much applicable to all? We're also challenging this score (calculated by the NVD, independently of the official CVE entry), also unsuccessfully so far.

If we were to remove the offending classes from 5.3.x, we would:

Anyone here can suggest improvements for this entry to the MITRE team by using the official form.

dkykuta commented 1 year ago

@bclozel Thank you for your answer. Most companies cannot verify project by project if it is using some class or not. They can only go as far as checking the dependencies and related vulnerabilities. I agree with you in that it would not fix the underlying problem, but it would mitigate the way this package exposes it and thus this CVE.

We are part of the people you mentioned. We don't use HttpInvokerServiceExporter but our security department is asking of us to "resolve" this critical vulnerability. They don't care if we are using this class or not. It is in the classpath, security tools are complaining about this, and they don't want that.

We cannot upgrade to java 17 just yet, and we don't know what to do. Does anyone have an alternative besides upgrading everything asap?

frankjkelly commented 1 year ago

I see both sides of this issue but I think Pivotal / Spring are better situated to leverage their position to help the very many teams and organizations impacted by this. This seems very like the December 2021 log4j debacle all over again (a big change going into holiday time for a lot of folks) and thankfully there Spring had great support and great hooks to help us get through that experience. Appreciate any assistance you can give. Thank you!

jnizet commented 1 year ago

Throwing an idea here: if the HttpInvokerServiceExporter is not used, but the class absolutely needs to be removed from the jar, how about doing just that: remove it from the jar? I.e. repackage the jar, store it under a different GAV in your company's repository, and use that repackaged library instead of the original jar.

bclozel commented 1 year ago

@dkykuta I know for a fact that it's impossible for any organization to have the expertise for all technologies listed in CVE entries. But it doesn't mean that one should only look at GAV coordinates and the CVSS score - especially when the main report doesn't contain any CVSS score and the content of the advisory is much more nuanced.

Your can suggest your security department to:

@jnizet I think that most security tools look at dependency GAVs and do not care about Jar contents. It's easy to work around an actual CVE: you can just shade the vulnerable dependency.

Jos31fr commented 1 year ago

@dkykuta we've challenged this report and still believe it is invalid. By the same logic, how can anyone be using Java in production when Java deserialization from untrusted sources is very much applicable to all? We're also challenging this score (calculated by the NVD, independently of the official CVE entry), also unsuccessfully so far.

What is the mean time of this procedure? If they completely reject your demand, have you any other plan to mitigate the issue? (like put this class in another artifact)

Nikhilkarande33 commented 1 year ago

@bclozel Will Vulnerability CVE-2016-1000027 for spring-web be fixed in 5.3.25?

I can see 5.3.25 will release in January 2023.

We can see latest non-vulnerable version is 6.0.1 but it requires java 17 upgrade which is not feasible for us at this moment.

Please suggest.

bclozel commented 1 year ago

@bclozel Will Vulnerability https://github.com/advisories/GHSA-4wrc-f8pq-fpqp for spring-web be fixed in 5.3.25?

No, see https://github.com/spring-projects/spring-framework/issues/24434#issuecomment-744519525

nate-biles commented 1 year ago

@bclozel How is HttpInvokerServiceExporter loaded as a bean? I'm wondering if it's even used. I don't see it being created directly, nor any methods called on it. It also has no @Component and it's not found in any configuration, also not used in spring.factories - how is it even loaded? Is there some other spring project I'm not using that loads it?

bclozel commented 1 year ago

@nate-biles by default, it's not. The application itself needs to declare it as a bean to enable this support.

dmitry-weirdo commented 1 year ago
==========
Total: 1 (CRITICAL: 1)
┌────────────────────────────────────────────────────────┬──────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────┐
│                        Library                         │  Vulnerability   │ Severity │ Installed Version │ Fixed Version │                          Title                          │
├────────────────────────────────────────────────────────┼──────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────┤
│ org.springframework:spring-web (spring-web-5.3.24.jar) │ CVE-2016-1000027 │ CRITICAL │ 5.3.24            │ 6.0.0         │ spring: HttpInvokerServiceExporter readRemoteInvocation │
│                                                        │                  │          │                   │               │ method untrusted java deserialization                   │
│                                                        │                  │          │                   │               │ https://avd.aquasec.com/nvd/cve-2016-1000027            │
└────────────────────────────────────────────────────────┴──────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────┘

This CVE started to fail now on spring-web-5.3.24.jar. The project cannot be yet migrated to Spring Boot 3 because of several bugs.

Should we — as it is always said by Spring for each and every CVE we post — ignore this CVE again?

bclozel commented 1 year ago

@dmitry-weirdo nothing has changed on the CVE as far as I know. Maybe your tool changed how its detection mechanism work? You should contact the tool vendor about that. You should not ignore this CVE if your application is deserializing untrusted content.

dmitry-weirdo commented 1 year ago

@bclozel Indeed, thanks for pointing out, this CVE should be already ignored for the dependency-check-maven that we use. It starts to fail again after a major version switch of this maven plugin.

https://github.com/jeremylong/DependencyCheck/issues/5331 — I added a ticket in the plugin's repo.

DRoppelt commented 1 year ago

I would like to share our workaround that we did in our organization where we have our own repository mirror. We download the jar, unpack it, drop the offending classes and repackage it as a different version. Similar to how some here have requested pivotal to do it in the official jar. We then customized our CVE reporting with "if you find the CVE in a jar that has this patchversion, it is a false positive"

The assumption is that the developers who have the largest issue with this CVE (as a false positive for their services)

a) are also going to be the ones that are a large (and inflexible) organization b) that therefore also hosts their own repository (Nexus, JFrog, etc.).

So I think this is worth sharing with everyone.

Here is a snippet of our pipeline (Jenkins):

stage('Download original jar') {
  steps {
    sh "rm -rf target"
    mvn("org.apache.maven.plugins:maven-dependency-plugin:3.4.0:copy \
       -Dartifact=org.springframework:spring-web:${springWebVersion}:jar \
       -DoutputDirectory=target")
  }
}
stage('Unpack&patch') {
  steps {
    script {
      dir("target") {
        sh "jar xvf spring-web-${springWebVersion}.jar"
        sh "rm -f spring-web-${springWebVersion}.jar"
        sh "rm -rf org/springframework/remoting/httpinvoker"
        sh "jar cf file.jar *"
      }
    }
  }
}
stage('Upload patch to nexus') {
  steps {
    mvn("deploy:deploy-file" +
        " -Dfile=target/file.jar" +
        " -DgroupId=org.springframework" +
        " -DartifactId=spring-web" +
        " -Dversion=${springWebVersion}.patchCVE-2016-1000027v${patchIteration}" +
        " -Dpackaging=jar" +
        " -Durl=https://yourartifactrepo/repository/releases" +
        " -DrepositoryId=repo-id-with-credentials"
    )
  }
}
accnetodevel commented 1 year ago

@DRoppelt, could we have unexpected spring-web behavior when removing http-invoker?

DRoppelt commented 1 year ago

@accnetodevel my understanding is that all classes in there are opt-in and wont come with any auto-configuration. You will have unexpected bevaviour if you are indeed using httpinvoker. I have not seen any issues with basic spring-web usage (simple CRUDs or spring-web solely present for Actuator endpoints).

starseedph commented 1 year ago

I would like to share our workaround that we did in our organization where we have our own repository mirror. We download the jar, unpack it, drop the offending classes and repackage it as a different version. Similar to how some here have requested pivotal to do it in the official jar. We then customized our CVE reporting with "if you find the CVE in a jar that has this patchversion, it is a false positive"

The assumption is that the developers who have the largest issue with this CVE (as a false positive for their services)

a) are also going to be the ones that are a large (and inflexible) organization b) that therefore also hosts their own repository (Nexus, JFrog, etc.).

So I think this is worth sharing with everyone.

Here is a snippet of our pipeline (Jenkins):

stage('Download original jar') {
  steps {
  sh "rm -rf target"
  mvn("org.apache.maven.plugins:maven-dependency-plugin:3.4.0:copy \
     -Dartifact=org.springframework:spring-web:${springWebVersion}:jar \
     -DoutputDirectory=target")
  }
}
stage('Unpack&patch') {
  steps {
  script {
    dir("target") {
      sh "jar xvf spring-web-${springWebVersion}.jar"
      sh "rm -f spring-web-${springWebVersion}.jar"
      sh "rm -rf org/springframework/remoting/httpinvoker"
      sh "jar cf file.jar *"
    }
  }
  }
}
stage('Upload patch to nexus') {
  steps {
  mvn("deploy:deploy-file" +
      " -Dfile=target/file.jar" +
      " -DgroupId=org.springframework" +
      " -DartifactId=spring-web" +
      " -Dversion=${springWebVersion}.patchCVE-2016-1000027v${patchIteration}" +
      " -Dpackaging=jar" +
      " -Durl=https://yourartifactrepo/repository/releases" +
      " -DrepositoryId=repo-id-with-credentials"
  )
  }
}

@DRoppelt So after removing it from the package, how did you reimplement it if you application is using httpinvoker? Thanks :)

DRoppelt commented 1 year ago

@starseedph the workaround assumes that you do not need anything the httpinvoker provided. Code that does not exist cannot be exploited. It is more or less mimicking what happened for spring-framework 6.X: it is now removed.

We did not reimplement it as I we are just not using it. We do everything by REST or as interactive HTML pages, no RMI/remoting.

qlwszl commented 1 year ago

组件详情(spring-framework-5.3.26),截止到目前,还有工具还在报出有高危漏洞,https://nvd.nist.gov/vuln/detail/CVE-2016-1000027。不知道漏洞是否还存在

bclozel commented 1 year ago

@qlwszl this is only a security issue if the component is used in an unsafe way (e.g. using untrusted input). For more details, see https://github.com/spring-projects/spring-framework/issues/24434#issuecomment-744519525

aakarshsingh commented 1 year ago

BTW, the documentation that is kept quoted over and over again in this thread now leads to a broken link.

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/integration.html#remoting-httpinvoker

EDIT: Can be accessible through 5.x tags

https://github.com/spring-projects/spring-framework/blob/v5.3.27/src/docs/asciidoc/integration.adoc#remoting-httpinvoker

arsadali commented 1 year ago

@starseedph the workaround assumes that you do not need anything the httpinvoker provided. Code that does not exist cannot be exploited. It is more or less mimicking what happened for spring-framework 6.X: it is now removed.

We did not reimplement it as I we are just not using it. We do everything by REST or as interactive HTML pages, no RMI/remoting.

So your solution is accepted by the organization and treating this as a fix?

DRoppelt commented 1 year ago

So your solution is accepted by the organization and treating this as a fix?

yep. Cannot exploit a remoting CVE if the classes do not exist. In a way, it is a self-made backport of the fix in 6.X

act-amirsky commented 1 year ago

Unfortunately, this would not satisfy everyone in the industry. Many big organizations rely on 3rd security vendors like BlackDuck or WhiteSource. BlackDuck would not recognize a mitigated version unless there was officially some public release made by someone. Such a release would relieve a lot of tension and pressure. Moving to Spring 6 is the ultimate solution of course but it comes with new requirements which are not easy for all clients of a vendors software to quickly adhere to (example Java 17) – so will take a long time to move over.

DRoppelt commented 1 year ago

BlackDuck would not recognize a mitigated version

sounds like an issue between big organizations and providers of rudimentary scanning tools that should not be taken at face value. A JdbcTemplate allows me to inject "DROP TABLE X" from input if not used correctly, but for some reason that is not a >9.0 CVE in all jdbc-esque libraries.

If you are using these tools without a way to overrule their results (i.e. allowing whitelisting their supposed findings), you keep busy for non-issues. This comment summarizes it quite well IMO https://github.com/spring-projects/spring-framework/issues/24434#issuecomment-744519525

akash-saha-jmh commented 1 year ago

Is there any plan to fix this cve on spring 5.x version?