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

incompatible_disallow_unverified_http_downloads: ignore plain `http` URLs (as opposed to `https` URLs) when downloading a file without given hash #8607

Closed
JLLeitschuh opened this issue Jun 11, 2019 · 12 comments

Comments

@JLLeitschuh
Copy link

commented Jun 11, 2019

mitm_build
Want to take over the Java ecosystem? All you need is a MITM!

The details in the blog post above describe my research over the past 4 months into the use of HTTP to resolve dependencies across the JVM ecosystem.

This vulnerability impacted the open source build infrastructure for organizations like the Apache Foundation, Eclipse Foundation, Jenkins, JetBrains, RedHat, ect...

One of the cases where I discovered this vulnerability was in the build infrastructure for some of Stripe's open source projects. They were declaring jar dependencies without an SHA checksum. Thus a MITM of their Bazel build could have allowed for the malicious compromise of their artifacts. For this finding, I was awarded a bug bounty by their security team.

I believe that it's the responsibility of API authors, especially of build tools to help protect their users from careless security vulnerabilities like this.

As such, I've begun work on fixing this for all users of Gradle in this PR:
gradle/gradle#9419

Additionally, I've opened an issue with the Apache Maven team about fixing this there as well:
https://issues.apache.org/jira/browse/MNG-6673

Internal Report

The internal (security private) report of this industry-wide vulnerability can be found here:
https://issuetracker.google.com/issues/132071216

Deliverables

  • Next minor release: Begin warning users about their use of HTTP to download dependencies.
  • Next major release: Force users to explicitly opt-out of the security offered by using HTTPS.
@laurentlb

This comment has been minimized.

Copy link
Member

commented Jun 12, 2019

Klaus, what do you think?
Maybe we could forbid HTTP dependencies without a sha256? Any good alternative?

@aehlig

This comment has been minimized.

Copy link
Member

commented Jun 13, 2019

Maybe we could forbid HTTP dependencies without a sha256?

That should work. What we most likely cannot drop is the "plain http but known-good checksum" use case. And of course, such a change can only become active in a release that allows incompatible changes.

@aehlig aehlig removed the untriaged label Jun 14, 2019

@aehlig

This comment has been minimized.

Copy link
Member

commented Jun 14, 2019

Proposed implementation https://bazel-review.googlesource.com/c/bazel/+/103031 (plus a flip of that flag, once we're in the next window that allows incompatible changes).

@laurentlb

This comment has been minimized.

Copy link
Member

commented Jun 14, 2019

Thanks!
Please send an email to bazel-dev@ for feedback about this change.

@aehlig

This comment has been minimized.

Copy link
Member

commented Jun 17, 2019

Please send an email to bazel-dev@ for feedback about this change.

https://groups.google.com/forum/#!topic/bazel-dev/sa0mkKXouoQ

@aehlig

This comment has been minimized.

Copy link
Member

commented Jun 18, 2019

Once https://bazel-review.googlesource.com/c/bazel/+/103031 is submitted, a flag --incompatible_disallow_unverified_http_downloads will be available that, if set, disallows downloads from http URLs if no checksum is provided.

Migration: add a checksum or at least one https source for fetching the file. Note that if no checksum is given, the http URLs will be ignored but it is no error if they are present, provided at least one non-http URL remains for the actual fetching. In this way, it is still possible to have the following mixed workflow. The developer updating the dependencies fetches from the authoritative https URL to compute the good hash and commits it. Everyone else would use the quick http-mirrors and verify against the committed hash.

@aehlig

This comment has been minimized.

Copy link
Member

commented Jun 18, 2019

@laurentlb Do we need a separate design document for that incompatible change, or is the information linked from this issue enough?

@dslomov

This comment has been minimized.

Copy link
Contributor

commented Jun 24, 2019

Please set a priority for this feature request.

@dslomov dslomov added the untriaged label Jun 24, 2019

@laurentlb laurentlb added P1 and removed untriaged labels Jun 24, 2019

@aehlig

This comment has been minimized.

Copy link
Member

commented Jul 12, 2019

Once https://bazel-review.googlesource.com/c/bazel/+/103031 is submitted, a flag --incompatible_disallow_unverified_http_downloads will be available that, if set, disallows downloads from http URLs if no checksum is provided.

Migration: add a checksum or at least one https source for fetching the file. Note that if no checksum is given, the http URLs will be ignored but it is no error if they are present, provided at least one non-http URL remains for the actual fetching. In this way, it is still possible to have the following mixed workflow. The developer updating the dependencies fetches from the authoritative https URL to compute the good hash and commits it. Everyone else would use the quick http-mirrors and verify against the committed hash.

This incompatible change has been approved. I will rebase the change and send it for review soon.

@aehlig aehlig changed the title Let's stop resolving dependencies over HTTP and require HTTPS incompatible_disallow_unverified_http_downloads: ignore plain `http` URLs (as opposed to `https` URLs) when downloading a file without given hash Jul 12, 2019

bazel-io pushed a commit that referenced this issue Jul 12, 2019
Deprecate plain HTTP downloads without checksum
Add a new incompatible flag. Once flipped, we disallow downloads of files
via plain HTTP unless a checksum is provided. Downloads via HTTPS as well
as downloads with a specified hash will still be allowed.

Background #8607

Change-Id: I95f6fa9e230401117de050173f3105ccc7fa7bb4
PiperOrigin-RevId: 257815568
bazel-io pushed a commit that referenced this issue Jul 17, 2019
bazel_repository_cache_test: explicitly allow unverified downloads fr…
…om localhost

The repository cache tests (among other things) that a download of a file adds it
to the cache under its sha256 hash, even if no hash was specified on the download.
To make the test certificate-independent, this is done via plain http on the
loopback device. Explicitly allow this use of unverified http download.

Related to #8607

Change-Id: I0140356b1d952c3ccdea78d5f35a2fa9d5926c84
PiperOrigin-RevId: 258557255
bazel-io pushed a commit that referenced this issue Jul 17, 2019
external_integration_test: provide hashsum, even if we expect a timeout
Since we run our tests for downloads via plain http, provide a checksum,
even in the case where we expect a timeout. In this way, prepare
our own code base for the #8607 flag flip.

Change-Id: I7ca9afb49008325975dff38b38aa1c596f0e9f83
PiperOrigin-RevId: 258565184
bazel-io pushed a commit that referenced this issue Jul 17, 2019
external_integration_test: provide needed checksum
In preparation of the flag flip in #8607, use a checksum for
our plain http-downloads.

Change-Id: I834abaccdb4b727f48c3dc2df8cd119839a85992
PiperOrigin-RevId: 258569601
bazel-io pushed a commit that referenced this issue Jul 22, 2019
repository context: on download, also consider integrity checksums su…
…fficient

The function download{,_and_extract} of a repository context allow to provide
checksums that the downloaded file has to have in order for the downlaod considered
to be successful. Traditionally, this was done by providing a parameter 'sha256';
however, it is also possible through the recently provided 'integrity' parameter,
that can take checksums in different form (currently supporting sha256 and sha512).
Consider such a checksum also sufficient for the requirement of not downloading
from plain http URLs without a given checksum introduced in #8607.

Change-Id: I164e1afcdb65124a361321603c7277dc635c05b9
PiperOrigin-RevId: 259323443
bazel-io pushed a commit that referenced this issue Jul 23, 2019
fix test_download_multiple
This test was trying to verify that if two download locations are provided,
both are recorded in the workspace_rules_log. It also tested that the
build completed successfully; however, the latter only happened by accident,
as the testing server would blindly return 200 and only then try to read
the file---and then crash, as file1.txt does not exist; so the file returned
had to relation at all to the file served at the second (valid, but never
accessed) URL. This was uncovered when adding a checksum in preparation of
the upcoming #8607 flag flip.

As the test is only about logging, put the use of download to the intended
form that all provided URLs are valid and return a file with the correct
hash.

Change-Id: I208ebffc5a724df7a75b2bced6fafbd8f50417eb
PiperOrigin-RevId: 259486544
bazel-io pushed a commit that referenced this issue Jul 23, 2019
skylark_repository_test: add checksums for http downloads
...so that our tests are compatible with the #8607 flag flip.

Change-Id: Ie2164b97c6be60cb58520352f8f7bcd7eb694fa8
PiperOrigin-RevId: 259507136
bazel-io pushed a commit that referenced this issue Jul 24, 2019
skylark_repository_test: remove tests asserting downloads without che…
…cksum

...over plain http to work. With the #8607 flag flip we
will be explicitly disallowing them.

Change-Id: I67e33cef57389656200b49e2d87fc372b813e3f6
PiperOrigin-RevId: 259687765
@JLLeitschuh

This comment has been minimized.

Copy link
Author

commented Jul 25, 2019

Thanks Bazel team for prioritizing this and working to protect your users and the JVM ecosystem.

@katre katre removed the migration-ready label Aug 2, 2019

bazel-io pushed a commit that referenced this issue Aug 5, 2019
//src/test/py/bazel:bazel_external_repository_test allow plain http d…
…ownload from 127.0.0.1

The loopback device is usually safe against man-in-the-middle attacks,
so allow these downloads in said test in preparation of #8607.

Change-Id: I9bc7c61719aea5a19350ea5f7af7ecce99387b5a
PiperOrigin-RevId: 261656498
bazel-io pushed a commit that referenced this issue Aug 5, 2019
Flip --incompatible_disallow_unverified_http_downloads to default to …
…true

As discussed in #8607, downloading files over plain http without reasonable
verification afterwards (e.g., checking the sha256 sum) is a security risk
and therefore should be discouraged. Flip the the corresponding flag disallowing
such downloads to true. The flag was available with default false already in 0.29,
and migration was possible even before that, simply by adding known-good checksums.

Change-Id: Ia3d46115996bf7b7c4aed56dcd15fa7317b5d4fa
PiperOrigin-RevId: 261662705
@aehlig

This comment has been minimized.

Copy link
Member

commented Aug 5, 2019

Closing, as the flag has been flipped in 299655e.

@aehlig aehlig closed this Aug 5, 2019

bazel-io pushed a commit that referenced this issue Aug 26, 2019
Wire up --incompatible_disallow_unverified_http_downloads for maven_s…
…erver

Force usage of either HTTPS or HTTP w/ SHA-1. Note that SHA-1 is still susceptible to collision attacks, but this should reduce the exploitable surface of the current implementation that allows plain HTTP without checksums.

Also see #6799 (comment)

Closes #9235.

RELNOTES: `maven_jar` and `maven_server` now disallow using plain HTTP URLs without a specified checksum. If you are still using `maven_jar`, consider migrating to [`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external) for transitive dependency management. See [#8607](#8607) for more information.

Change-Id: I61b96b1d797071dc84291fecbf05a45d927240a5
PiperOrigin-RevId: 265442213
@JLLeitschuh

This comment has been minimized.

Copy link
Author

commented Sep 9, 2019

Sanity check: Does this check that any redirects are HTTPS based as well, or only the declared host is HTTPS based?

In Gradle, we are checking both that the declared host is HTTPS based, and all redirects are HTTPS based as well.
gradle/gradle#10065

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.