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

Replaces ZipInputStream with ZipFile to fix Zip Slip vulnerability #7230

Merged
merged 11 commits into from Apr 28, 2023

Conversation

DarshitChanpura
Copy link
Member

More details about the vulenrability can be found on https://github.com/snyk/zip-slip-vulnerability

Description

ZipInputStream can cause a potential zipslip vulnerability. This PR aims at fixing the vulnerability by replacing it with ZipFile class.

Issues Resolved

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff
  • Commit changes are listed out in CHANGELOG.md file (See: Changelog)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@@ -749,12 +752,11 @@ private Path unzip(Path zip, Path pluginsDir) throws IOException, UserException
if (entry.isDirectory() == false) {
try (OutputStream out = Files.newOutputStream(targetFile)) {
int len;
while ((len = zipInput.read(buffer)) >= 0) {
while ((len = zipFile.getInputStream(entry).read(buffer)) >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this reopens the stream every time we loop (or relies on the fact that zipFile.getInputStream memoizes a stream), let's do it once?

Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good if you can please make gradle check pass + address my comment on stream reuse and changelog entry. Thanks!

CHANGELOG.md Outdated
@@ -79,6 +79,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Fix compression support for h2c protocol ([#4944](https://github.com/opensearch-project/OpenSearch/pull/4944))
- Support OpenSSL Provider with default Netty allocator ([#5460](https://github.com/opensearch-project/OpenSearch/pull/5460))
- Avoid negative memory result in IndicesQueryCache stats calculation ([#6917](https://github.com/opensearch-project/OpenSearch/pull/6917))
- Replaces ZipInputStream with ZipFile to fix ZipSlip vulnerability ([#7230](https://github.com/opensearch-project/OpenSearch/pull/7230))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace "fix ZipSlip..." by "fix CVE-..."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know of a specific CVE for this vulnerability. But I do see a group of different vulnerabilities related to zip slip exploit. Refer here for more details:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I don't see a CVE in the list on https://github.com/snyk/zip-slip-vulnerability either.

I think the correct spelling is with a space though, isn't it? "Zip Slip".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

More details about the vulenrability can be found on https://github.com/snyk/zip-slip-vulnerability

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@DarshitChanpura
Copy link
Member Author

Need to re-run Gradle Precommit. The failure seems to be flaky on the Github runner's end.

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@@ -748,13 +751,13 @@ private Path unzip(Path zip, Path pluginsDir) throws IOException, UserException
}
if (entry.isDirectory() == false) {
try (OutputStream out = Files.newOutputStream(targetFile)) {
InputStream input = zipFile.getInputStream(entry);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the input stream not need to be closed, including on error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will add input.close().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to close it in a finally block, otherwise it will leak on read error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include it in the try-with-resources:

try (OutputStream out = Files.newOutputStream(targetFile);
    InputStream input = zipFile.getInputStream(entry)) {
...
}

@@ -78,3 +80,28 @@ thirdPartyAudit.ignoreViolations(
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSExtendedMasterSecretGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSExtendedMasterSecretGenerator$2'
)

thirdPartyAudit.ignoreMissingClasses(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without these, the task ':distribution:tools:plugin-cli:thirdPartyAudit' fails. See details here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reta do you know if this is ok?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reta do you know if this is ok?

Yeah, I think this is fine, the common-compress may have optional dependencies on ZSTD and other codecs, so we need to exclude these classes (we don't use these codecs here)

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@codecov-commenter
Copy link

codecov-commenter commented Apr 24, 2023

Codecov Report

Merging #7230 (a828a70) into main (e1da84d) will increase coverage by 0.03%.
The diff coverage is 100.00%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@             Coverage Diff              @@
##               main    #7230      +/-   ##
============================================
+ Coverage     70.65%   70.69%   +0.03%     
+ Complexity    59518    59486      -32     
============================================
  Files          4859     4859              
  Lines        285527   285527              
  Branches      41150    41149       -1     
============================================
+ Hits         201749   201861     +112     
+ Misses        67216    67051     -165     
- Partials      16562    16615      +53     
Impacted Files Coverage Δ
...a/org/opensearch/plugins/InstallPluginCommand.java 85.14% <100.00%> (ø)

... and 501 files with indirect coverage changes

@DarshitChanpura DarshitChanpura marked this pull request as ready for review April 24, 2023 18:02
@DarshitChanpura DarshitChanpura changed the title Replaces ZipInputStream with ZipFile to fix ZipSlip vulnerability Replaces ZipInputStream with ZipFile to fix zip slip vulnerability Apr 24, 2023
@DarshitChanpura DarshitChanpura changed the title Replaces ZipInputStream with ZipFile to fix zip slip vulnerability Replaces ZipInputStream with ZipFile to fix Zip Slip vulnerability Apr 24, 2023
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@DarshitChanpura
Copy link
Member Author

Gradle precommit failure seems to be a memory issue with GIthub runner. Re-run should probably solve it.

@@ -78,3 +80,28 @@ thirdPartyAudit.ignoreViolations(
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSExtendedMasterSecretGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSExtendedMasterSecretGenerator$2'
)

thirdPartyAudit.ignoreMissingClasses(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reta do you know if this is ok?

byte[] buffer = new byte[8192];
while ((entry = zipInput.getNextEntry()) != null) {
while (entries.hasMoreElements()) {
entry = entries.nextElement();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does entries.nextElment() return null when there are no more entries? You could collapse the loop in that case without needing to check entries.hasMoreElements() into while (entry = entries.nextElement()) { }.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entries.nextElement() returns NoSucElementException when no more elements exist.
According to definition:

Throws:
NoSuchElementException – if no more elements exist.

@@ -748,13 +751,13 @@ private Path unzip(Path zip, Path pluginsDir) throws IOException, UserException
}
if (entry.isDirectory() == false) {
try (OutputStream out = Files.newOutputStream(targetFile)) {
InputStream input = zipFile.getInputStream(entry);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to close it in a finally block, otherwise it will leak on read error.

@@ -748,13 +751,14 @@ private Path unzip(Path zip, Path pluginsDir) throws IOException, UserException
}
if (entry.isDirectory() == false) {
try (OutputStream out = Files.newOutputStream(targetFile)) {
InputStream input = zipFile.getInputStream(entry);
Copy link
Collaborator

@reta reta Apr 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to @dblock and @andrross comments, and please use zipInput.transferTo(out);

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@dblock dblock merged commit 8422768 into opensearch-project:main Apr 28, 2023
8 checks passed
@dblock dblock added the backport 2.x Backport to 2.x branch label Apr 28, 2023
@opensearch-trigger-bot
Copy link
Contributor

The backport to 2.x failed:

The process '/usr/bin/git' failed with exit code 128

To backport manually, run these commands in your terminal:

# Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add ../.worktrees/backport-2.x 2.x
# Navigate to the new working tree
pushd ../.worktrees/backport-2.x
# Create a new branch
git switch --create backport/backport-7230-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 84227681555b4aec12725c4454c39834cb6839d2
# Push it to GitHub
git push --set-upstream origin backport/backport-7230-to-2.x
# Go back to the original working tree
popd
# Delete the working tree
git worktree remove ../.worktrees/backport-2.x

Then, create a pull request where the base branch is 2.x and the compare/head branch is backport/backport-7230-to-2.x.

@dblock
Copy link
Member

dblock commented Apr 28, 2023

@DarshitChanpura want to manually backport to 2.x?

DarshitChanpura added a commit to DarshitChanpura/OpenSearch that referenced this pull request May 2, 2023
…pensearch-project#7230)

* Replaces ZipInputStream with ZipFile to fix ZipSlip vulnerability

More details about the vulenrability can be found on https://github.com/snyk/zip-slip-vulnerability

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds a CHANGELOG entry

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Changes the base package for ZipFile to avoid forbiddenApisError

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates SHAs

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds LICENSE and NOTICE files for commons-compress package

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates thirdParty ignoreMissingClasses list

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Closes input stream

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes NoSuchFileException when reading files

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes spotless errors

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes CHANGELOG.md

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Addresses PR comments

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

---------

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
(cherry picked from commit 8422768)
dblock pushed a commit that referenced this pull request May 3, 2023
…7230) (#7366)

* Replaces ZipInputStream with ZipFile to fix ZipSlip vulnerability

More details about the vulenrability can be found on https://github.com/snyk/zip-slip-vulnerability

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds a CHANGELOG entry

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Changes the base package for ZipFile to avoid forbiddenApisError

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates SHAs

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds LICENSE and NOTICE files for commons-compress package

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates thirdParty ignoreMissingClasses list

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Closes input stream

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes NoSuchFileException when reading files

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes spotless errors

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes CHANGELOG.md

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Addresses PR comments

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

---------

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
(cherry picked from commit 8422768)
shiv0408 pushed a commit to Gaurav614/OpenSearch that referenced this pull request Apr 25, 2024
…pensearch-project#7230)

* Replaces ZipInputStream with ZipFile to fix ZipSlip vulnerability

More details about the vulenrability can be found on https://github.com/snyk/zip-slip-vulnerability

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds a CHANGELOG entry

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Changes the base package for ZipFile to avoid forbiddenApisError

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates SHAs

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Adds LICENSE and NOTICE files for commons-compress package

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Updates thirdParty ignoreMissingClasses list

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Closes input stream

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes NoSuchFileException when reading files

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes spotless errors

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Fixes CHANGELOG.md

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

* Addresses PR comments

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>

---------

Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
Signed-off-by: Shivansh Arora <hishiv@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 2.x Backport to 2.x branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants