Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
gauravdeshmukh612 opened this issue Jan 27, 2020 · 78 comments
Closed

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

gauravdeshmukh612 opened this issue Jan 27, 2020 · 78 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@gauravdeshmukh612
Copy link

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

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 27, 2020
@bclozel
Copy link
Member

bclozel commented Jan 27, 2020

This been addressed already in the documentation, as explained in the report you've copy/pasted here: see the reference documentation.

@bclozel bclozel closed this as completed Jan 27, 2020
@bclozel bclozel added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 27, 2020
@halhelal
Copy link

If this is a matter of documentation, then this needs to be communicated with NVD. Currently, the base score is critical 9.8 and some scanners are throwing this as highly vulnerable.

https://nvd.nist.gov/vuln/detail/CVE-2016-1000027

@rstoyanchev
Copy link
Contributor

@halhelal I think there is a misunderstanding.

There is no fix for this vulnerability. Java serialization is unsafe, and all we can do is advise against exposing HTTP Invoker endpoints to untrusted clients in our documentation. That we have done almost 5 years ago when this CVE was first published. However, it does not make the vulnerability go away, nor does it change its score.

Why the CVE was republished again this month, I do not know. We did not publish it in the first place so it is not ours to begin with. Having said that it can be used as a reminder to check that there are no HTTP Invoker endpoints exposed to untrusted clients. If there are none, then nothing further to do.

@sebady
Copy link

sebady commented Feb 3, 2020

Is there a possibility to split out the HTTP invoker functionality (i.e. the package org.springframework.remoting.httpinvoker) into a separate artifact from remaining functionality in spring-web? This way clients of spring-web can sidestep (through dependency management) the portion that is considered "vulnerable" in the CVE and still use the remaining functionality of spring-web? I'm not sure how yet to re-structure spring-web to allow this.

@bclozel
Copy link
Member

bclozel commented Feb 3, 2020

Doing this would be a breaking change and we would need to create a new artifact for that. This is typically the type of change we apply for major releases.

These classes have been part of spring-web since Spring Framework 1.1.

I guess it's hard to balance the severity of the issue and the amount of unsafe setup required to trigger it. Tools warning about such vulnerabilities don't usually have that context and they can only convey more information to users about the context of this vulnerability.

In this case, and especially since this new warning seems to be a misunderstanding, I don't think we should move this code now.

@tgit24
Copy link

tgit24 commented Feb 4, 2020

I think spring team should contact NVD to know why this vulnerability all the sudden get raised to 9.8 ??

@rstoyanchev
Copy link
Contributor

@tgit24 this has already been answered above.

@bclozel
Copy link
Member

bclozel commented Feb 5, 2020

We reached out to MITRE and apparently this CVE id was allocated in 2016 but never got published as it should have been, since all other references were already public. The original CNA (CVE Numbering Authority) which allocated this id got disbanded and MITRE is merely cleaning the backlog since it took over.

Publishing this outdated CVE had the effect of triggering numerous security tools - unfortunately, there's nothing more we can do here.

TL;DR: this is an old CVE, the information is still relevant and it can't be "fixed" in Spring Framework since it's about avoiding to expose HTTP Invoker endpoints to untrusted clients - there's been an official warning about this in our documentation for years now.

@tomcruise81
Copy link

@bclozel - what about breaking it out into a separate dependency, that is by default referenced by spring-web, but would give application teams the option to exclude it at their own discretion?

Or is it so tightly intertwined with the way that spring-web works that that's not possible?

@berlinbrown
Copy link

This is still issue today, aqua scans, nexus iq scans. Veracode scans. 1000027, is there a way to get around it from the scan perspective, possibly excluding a specific jar. Sounds like spring-web can't exclude. Especially with spring boot, if you include the parent, have to include a lot of other stuff.

@bclozel
Copy link
Member

bclozel commented Jul 9, 2020

This will be addressed in #25379

@cvmocanu
Copy link

First, I want to thank the Spring Framework team for doing a great work - we are many developers depending on you guys.

@bclozel : that ticket just deprecate the class, and it will be removed in Spring 6.

This is a big problem because:

  • the NexusIQ in the company I work for tags spring-web as unacceptable because of CVE-2016-1000027. I'm sure others face similar issues.
  • it's very doubtful that we will be allowed to change the NexusIQ rules, since this is a real critical vulnerability

Given the above, the solutions I see are:

  • hack the build process to delete that class from the jar; in addition to being a huge hack, I'm not even sure if it would work (since the scanner may just look at the maven GAV coordinates, not at the classes inside the jar).
  • give up spring-web; Webflux would be an alternative, but it comes with too many disadvantages (e.g. uninformative thread dumps, complicated java code, etc.) and it gives no advantage back if you don't have a fully reactive stack (all the way to the database). In addition, if you don't need the performance, you pay the costs without getting the advantages. Since there is no good blocking alternative to spring-web, this means giving up spring web for some other web framework. Since spring-boot needs either spring-web or webflux, this also means giving up spring-boot. And if we give up that, we might as well give up spring entirely.

As you can see, this is a huge issue, and we need a solution way before Spring 6 will be released (I couldn't find an estimated release date).

Producing a separate artifact (spring-web-clean?) that doesn't contain any class doing java serialization should fix the issue.

@tomcruise81's suggestion above might not work if the scanner just looks at the GAV coordinates.

@bclozel
Copy link
Member

bclozel commented Dec 14, 2020

Hi @cvmocanu

Thanks for reaching out - and thanks for being part of the community!
I'm sorry about the situation you're facing; I've been chatting on gitter/mail with people about this particular situation. Many developers are having the same issue in their organization.

For the sake of this thread, I'll quickly summarize the situation again:

A variant of CVE-2011-2894 was submitted in 2016 by security researchers to a now disbanded CNA (CVE Numbering Authority). Years later, in 2020, this CVE was published by another CNA as a way to process all outstanding reports.

This issue is another variant of "Java deserialization from untrusted sources". Doing so is exposing your application to remote code execution. This vulnerability is present at the JDK level as well, no Spring involved. This is why we've documented over the years, that developers should pay attention to that point. In this case, as opposed to 2011, the highest critical score is triggering all kind of automated rules...

Given the current trends and the security challenges, we've decided to remove this particular support in #25379.

We know that deprecating that class does not solve the problem at hand for development teams. Given that CVE report, we're not even sure that those automated rules will stop applying to those tools in the future when the class will be deleted - in fact, this CVE report is tagged for Spring Framework 4.1.4 but it still applies to 5.x, so I guess vendors are adding metadata in their systems?

Back to your situation @cvmocanu. The main problem here is that this security process comes without any context: from the critical score of the initial CVE to the rules enforced in your NexusIQ instance, most of it is done automatically. If companies around the world would be strictly enforcing this rule without context, there would be no Spring MVC nor any kind of Java application accepting traffic deployed in production since 2011: they're all "vulnerable".

I guess that tools like NexusIQ aren't doing static code analysis but rather just looking at the dependency graph - otherwise they wouldn't flag your application: looking for HTTPInvokerServiceExporter or RemoteInvocationSerializingExporter usage in the application code would be an easy way to prevent most false positives.

We don't think the solutions you're thinking about will solve the problem:

  • As said above, security tools are probably looking at the dependency graph only. Removing the class is not likely to solve the problem. Shading the library might work, but you're really working around security rules and likely to miss genuine CVE alerts in the future.

  • When it comes to modules, Spring MVC is spring-webmvc and Spring WebFlux is spring-webflux. spring-web is the shared infrastructure for both Web Frameworks. A WebFlux app still depends on spring-web.

I'd suggest sharing your experience with your security team and security vendor: if developers need to consider switching development stack completely because tools and processes raise false positives (again, if your application does not deserialize Java from untrusted sources, your app is safe in that regard!), there's a broader problem that needs to be addressed.

Producing new artifacts every time a problem like that happens is not sustainable technically and as a community. It feels like we're trying to solve organizational issues from a pure technical perspective, and this rarely works. I'd be happy to chat with your security team/vendor about this particular problem. Feel free to reach out to me (my contact info is on my github profile).

@bclozel bclozel changed the title Sonartype vulnerability CVE-2016-1000027 in Spring-web project Sonatype vulnerability CVE-2016-1000027 in Spring-web project Dec 14, 2020
@Mert-Z
Copy link

Mert-Z commented Jan 21, 2021

First, I want to thank the Spring Framework team for doing a great work - we are many developers depending on you guys.

@bclozel : that ticket just deprecate the class, and it will be removed in Spring 6.

This is a big problem because:

  • the NexusIQ in the company I work for tags spring-web as unacceptable because of CVE-2016-1000027. I'm sure others face similar issues.
  • it's very doubtful that we will be allowed to change the NexusIQ rules, since this is a real critical vulnerability

Given the above, the solutions I see are:

  • hack the build process to delete that class from the jar; in addition to being a huge hack, I'm not even sure if it would work (since the scanner may just look at the maven GAV coordinates, not at the classes inside the jar).
  • give up spring-web; Webflux would be an alternative, but it comes with too many disadvantages (e.g. uninformative thread dumps, complicated java code, etc.) and it gives no advantage back if you don't have a fully reactive stack (all the way to the database). In addition, if you don't need the performance, you pay the costs without getting the advantages. Since there is no good blocking alternative to spring-web, this means giving up spring web for some other web framework. Since spring-boot needs either spring-web or webflux, this also means giving up spring-boot. And if we give up that, we might as well give up spring entirely.

As you can see, this is a huge issue, and we need a solution way before Spring 6 will be released (I couldn't find an estimated release date).

Producing a separate artifact (spring-web-clean?) that doesn't contain any class doing java serialization should fix the issue.

@tomcruise81's suggestion above might not work if the scanner just looks at the GAV coordinates.

just as a note, Webflux also pulls in spring-web as a dependency;

[INFO] |  +- org.springframework.boot:spring-boot-starter-webflux:jar:2.4.2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-json:jar:2.4.2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-reactor-netty:jar:2.4.2:compile
[INFO] |  |  |  \- io.projectreactor.netty:reactor-netty-http:jar:1.0.3:compile
[INFO] |  |  |     +- io.netty:netty-codec-http:jar:4.1.58.Final:compile
[INFO] |  |  |     |  +- io.netty:netty-common:jar:4.1.58.Final:compile
[INFO] |  |  |     |  +- io.netty:netty-buffer:jar:4.1.58.Final:compile
[INFO] |  |  |     |  +- io.netty:netty-transport:jar:4.1.58.Final:compile
[INFO] |  |  |     |  +- io.netty:netty-codec:jar:4.1.58.Final:compile
[INFO] |  |  |     |  \- io.netty:netty-handler:jar:4.1.58.Final:compile
[INFO] |  |  |     +- io.netty:netty-codec-http2:jar:4.1.58.Final:compile
[INFO] |  |  |     +- io.netty:netty-resolver-dns:jar:4.1.58.Final:compile
[INFO] |  |  |     |  +- io.netty:netty-resolver:jar:4.1.58.Final:compile
[INFO] |  |  |     |  \- io.netty:netty-codec-dns:jar:4.1.58.Final:compile
[INFO] |  |  |     +- io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.1.58.Final:compile
[INFO] |  |  |     |  \- io.netty:netty-transport-native-unix-common:jar:4.1.58.Final:compile
[INFO] |  |  |     +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.58.Final:compile
[INFO] |  |  |     \- io.projectreactor.netty:reactor-netty-core:jar:1.0.3:compile
[INFO] |  |  |        \- io.netty:netty-handler-proxy:jar:4.1.58.Final:compile
[INFO] |  |  |           \- io.netty:netty-codec-socks:jar:4.1.58.Final:compile
[INFO] |  |  +- org.springframework:spring-web:jar:5.3.3:compile

@tomcruise81
Copy link

To add context, I believe the the GAV coordinates are sufficient:

Here's Nexus IQ's analysis of an older version of spring-web:

image

And here's it's analysis of an older version of spring-expression, which suffered from CVE-2018-1270:

image

Note that for spring-expression, possible remediation is to upgrade to 4.3.17:

Select 4.3.17.RELEASE: Next version with no policy violation

So it does appear that GAV coordinates should be sufficient.

@bclozel
Copy link
Member

bclozel commented Jan 22, 2021

I'm not sure that helps unfortunately @tomcruise81

In the case of CVE-2018-1270, the CVE metadata itself contains a "patched version" information pointing to 4.3.16.RELEASE (as mentioned in the official CVE report). Is there a particular reason 4.3.17.RELEASE is selected here instead?

In our case here, there is no "patched version" information attached to the CVE report. It looks like we're dealing here with a 4.1.4-* version range. By the time the offending classes are removed from the JAR, the version range will still be there. We'll have to get in touch with MITRE and vendors to update this information - technically the current information is already not 100% accurate.

@artem-smotrakov
Copy link

FYI

Vulnerable applications can be detected using static code analysis.

If you use CodeQL, I've created two CodeQL queries that detect vulnerable service exporters:

This blog post describes the issue, shows an example of vulnerable code, and describes the queries.

@cvmocanu
Copy link

cvmocanu commented Jul 30, 2021

It's very disappointing to see the Spring team refusing to split the vulnerable class into a separate module. This would indeed be a braking change (people who actually use that class would have to manually bring-in a new dependency), but I think it would affect very few people.

Pushing for better tools (like CodeQL, if it's indeed better) is a fair point, and I'm going to try to at least get it considered, but it may take many months (or even years) in a large organization to change tools.
In the mean time, we have to feel the pain.
And while the source of the pain is the processes of the organization, it wouldn't be too difficult for the Spring team to fix this issue.

Another thing to ponder: why is it that, from 276 libraries, spring-web is the only one that causes issues?

@dmitry-weirdo
Copy link

dmitry-weirdo commented Jan 17, 2023

==========
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
Copy link
Member

bclozel commented Jan 17, 2023

@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
Copy link

@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.

jeremylong/DependencyCheck#5331 — I added a ticket in the plugin's repo.

@DRoppelt
Copy link

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
Copy link

accnetodevel commented Jan 20, 2023

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

@DRoppelt
Copy link

@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
Copy link

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
Copy link

@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
Copy link

qlwszl commented Apr 11, 2023

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

@bclozel
Copy link
Member

bclozel commented Apr 11, 2023

@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 #24434 (comment)

@aakarshsingh
Copy link

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

@arsadali
Copy link

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests