CVE-2018-25046 (Go, published 2022-12-27T22:15Z)
Description: value: Due to improper path sanitization, archives containing relative file paths can cause files to be written (or overwritten) outside of the target directory.
Severity: nan (CVSS v3 base score: 9.1)
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/cloudfoundry/archiver
Files changed:
extractor/extractor_test.go
extractor/tgz_extractor.go
extractor/zip_extractor.go
Commit message: Refactored the path resolution to use securejoin

[#157757626]

Signed-off-by: Edwin Xie <exie@pivotal.io>


Vulnerable code:
	filePath := filepath.Join(dest, header.Name)
	err := os.MkdirAll(filepath.Dir(filePath), 0755)
	filePath := filepath.Join(dest, file.Name)
		err := os.MkdirAll(filePath, fileInfo.Mode())
		err := os.MkdirAll(filepath.Dir(filePath), 0755)

Fixed code:

			Context("with a bad zip archive", func() {
				BeforeEach(func() {
					test_helper.CreateZipArchive(extractionSrc, []test_helper.ArchiveFile{
						{
							Name: "../some-file",
							Body: "file-in-bad-dir-contents",
						},
					})
				})

				It("returns an error", func() {
					subdir := filepath.Join(extractionDest, "subdir")
					Expect(os.Mkdir(subdir, 0777)).To(Succeed())
					err := extractor.Extract(extractionSrc, subdir)
					Expect(err).To(HaveOccurred())
				})
			})

			Context("with a bad zip archive", func() {
				BeforeEach(func() {
					test_helper.CreateZipArchive(extractionSrc, []test_helper.ArchiveFile{
						{
							Name: "../some-file",
							Body: "file-in-bad-dir-contents",
						},
					})
				})

				It("does not insecurely extract the file outside of the provided destination", func() {
					subdir := filepath.Join(extractionDest, "subdir")
					Expect(os.Mkdir(subdir, 0777)).To(Succeed())
					err := extractor.Extract(extractionSrc, subdir)
					Expect(err).NotTo(HaveOccurred())

					Expect(filepath.Join(extractionDest, "some-file")).NotTo(BeAnExistingFile())
					Expect(filepath.Join(subdir, "some-file")).To(BeAnExistingFile())
				})
			})

			Context("with a bad tgz archive", func() {
				BeforeEach(func() {
					test_helper.CreateTarGZArchive(extractionSrc, []test_helper.ArchiveFile{
						{
							Name: "../some-file",
							Body: "file-in-bad-dir-contents",
						},
					})
				})

				It("returns an error", func() {
					subdir := filepath.Join(extractionDest, "subdir")
					Expect(os.Mkdir(subdir, 0777)).To(Succeed())
					err := extractor.Extract(extractionSrc, subdir)
					Expect(err).To(HaveOccurred())
				})
			})

			Context("with a bad tgz archive", func() {
				BeforeEach(func() {
					test_helper.CreateTarGZArchive(extractionSrc, []test_helper.ArchiveFile{
						{
							Name: "../some-file",
							Body: "file-in-bad-dir-contents",
						},
					})
				})

				It("does not insecurely extract the file outside of the provided destination", func() {
					subdir := filepath.Join(extractionDest, "subdir")
					Expect(os.Mkdir(subdir, 0777)).To(Succeed())
					err := extractor.Extract(extractionSrc, subdir)
					Expect(err).NotTo(HaveOccurred())
					Expect(filepath.Join(extractionDest, "some-file")).NotTo(BeAnExistingFile())
					Expect(filepath.Join(subdir, "some-file")).To(BeAnExistingFile())
				})
			})

		Context("with a bad tar archive", func() {
			BeforeEach(func() {
				test_helper.CreateTarArchive(extractionSrc, []test_helper.ArchiveFile{
					{
						Name: "../some-file",
						Body: "file-in-bad-dir-contents",
					},
				})
			})

			It("does not insecurely extract the file outside of the provided destination", func() {
				subdir := filepath.Join(extractionDest, "subdir")
				Expect(os.Mkdir(subdir, 0777)).To(Succeed())
				err := extractor.Extract(extractionSrc, subdir)
				Expect(err).NotTo(HaveOccurred())
				Expect(filepath.Join(extractionDest, "some-file")).NotTo(BeAnExistingFile())
				Expect(filepath.Join(subdir, "some-file")).To(BeAnExistingFile())
			})
		})

	securejoin "github.com/cyphar/filepath-securejoin"
	filePath, err := securejoin.SecureJoin(dest, header.Name)
	if err != nil {
		return err
	}
	err = os.MkdirAll(filepath.Dir(filePath), 0755)

	securejoin "github.com/cyphar/filepath-securejoin"
	filePath, err := securejoin.SecureJoin(dest, file.Name)
		err = os.MkdirAll(filePath, fileInfo.Mode())
		err = os.MkdirAll(filepath.Dir(filePath), 0755)