#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "chrome/services/file_util/public/cpp/sandboxed_zip_analyzer.h"
#include <stdint.h>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/safe_browsing/archive_analyzer_results.h"
#include "chrome/services/file_util/fake_file_util_service.h"
#include "chrome/services/file_util/file_util_service.h"
#include "chrome/services/file_util/public/mojom/safe_archive_analyzer.mojom.h"
#include "components/safe_browsing/core/common/features.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "crypto/sha2.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
#if BUILDFLAG(IS_MAC)
const char kAppInZipHistogramName[] =
"SBClientDownload.ZipFileContainsAppDirectory";
#endif
_;
}
class SandboxedZipAnalyzerTest : public ::testing::Test { … };
const uint8_t SandboxedZipAnalyzerTest::kUnsignedDigest[] = …;
const uint8_t SandboxedZipAnalyzerTest::kSignedDigest[] = …;
const uint8_t SandboxedZipAnalyzerTest::kJSEFileDigest[] = …;
const SandboxedZipAnalyzerTest::BinaryData
SandboxedZipAnalyzerTest::kUnsignedExe = …;
const SandboxedZipAnalyzerTest::BinaryData
SandboxedZipAnalyzerTest::kSignedExe = …;
const SandboxedZipAnalyzerTest::BinaryData SandboxedZipAnalyzerTest::kJSEFile = …;
#if BUILDFLAG(IS_MAC)
const uint8_t SandboxedZipAnalyzerTest::kUnsignedMachODigest[] = {
0xe4, 0x62, 0xff, 0x75, 0x2f, 0xf9, 0xd8, 0x4e, 0x34, 0xd8, 0x43,
0xe5, 0xd4, 0x6e, 0x20, 0x12, 0xad, 0xcb, 0xd4, 0x85, 0x40, 0xa8,
0x47, 0x3f, 0xb7, 0x94, 0xb2, 0x86, 0xa3, 0x89, 0xb9, 0x45};
const SandboxedZipAnalyzerTest::BinaryData
SandboxedZipAnalyzerTest::kUnsignedMachO = {
"app-with-executables.app/Contents/MacOS/executablefat",
safe_browsing::ClientDownloadRequest_DownloadType_WIN_EXECUTABLE,
&kUnsignedMachODigest[0],
16640,
false,
};
const uint8_t SandboxedZipAnalyzerTest::kSignedMachODigest[] = {
0x59, 0x0b, 0xc9, 0xc8, 0xee, 0x6c, 0xec, 0x94, 0x46, 0xc1, 0x44,
0xd8, 0xea, 0x2b, 0x10, 0x85, 0xb1, 0x5b, 0x5c, 0x68, 0x80, 0x9b,
0x2c, 0x27, 0x48, 0xad, 0x04, 0x0c, 0x2a, 0x1e, 0xf8, 0x29};
const SandboxedZipAnalyzerTest::BinaryData
SandboxedZipAnalyzerTest::kSignedMachO = {
"app-with-executables.app/Contents/MacOS/signedexecutablefat",
safe_browsing::ClientDownloadRequest_DownloadType_WIN_EXECUTABLE,
&kSignedMachODigest[0],
34176,
true,
};
#endif
TEST_F(SandboxedZipAnalyzerTest, NoBinaries) { … }
TEST_F(SandboxedZipAnalyzerTest, OneUnsignedBinary) { … }
TEST_F(SandboxedZipAnalyzerTest, TwoBinariesOneSigned) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedArchiveNoBinaries) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedNestedArchive) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedTooManyNestedArchive) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedRarArchiveNoBinaries) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedArchiveAndBinaries) { … }
TEST_F(SandboxedZipAnalyzerTest,
ZippedArchiveAndBinariesWithTrailingSpaceAndPeriodChars) { … }
TEST_F(SandboxedZipAnalyzerTest, ZippedJSEFile) { … }
TEST_F(SandboxedZipAnalyzerTest, EncryptedZip) { … }
TEST_F(SandboxedZipAnalyzerTest, EncryptedZipWrongPassword) { … }
TEST_F(SandboxedZipAnalyzerTest, EncryptedZipAes) { … }
TEST_F(SandboxedZipAnalyzerTest, EncryptedZipAesNoPassword) { … }
#if BUILDFLAG(IS_MAC)
TEST_F(SandboxedZipAnalyzerTest, ZippedAppWithUnsignedAndSignedExecutable) {
base::HistogramTester histograms;
histograms.ExpectTotalCount(kAppInZipHistogramName, 0);
safe_browsing::ArchiveAnalyzerResults results;
RunAnalyzer(dir_test_data_.AppendASCII(
"mach_o/zipped-app-two-executables-one-signed.zip"),
&results);
EXPECT_TRUE(results.success);
EXPECT_TRUE(results.has_executable);
EXPECT_FALSE(results.has_archive);
bool found_unsigned = false;
bool found_signed = false;
for (const auto& binary : results.archived_binary) {
if (kSignedMachO.file_path == binary.file_path()) {
found_signed = true;
ExpectBinary(kSignedMachO, binary);
}
if (kUnsignedMachO.file_path == binary.file_path()) {
found_unsigned = true;
ExpectBinary(kUnsignedMachO, binary);
}
}
if (!found_unsigned || !found_signed) {
LOG(ERROR) << "Expected to find: " << kSignedMachO.file_path << " and "
<< kUnsignedMachO.file_path;
for (const auto& binary : results.archived_binary) {
LOG(ERROR) << "Found " << binary.file_path();
}
}
EXPECT_TRUE(found_unsigned);
EXPECT_TRUE(found_signed);
}
#endif
TEST_F(SandboxedZipAnalyzerTest, CanDeleteDuringExecution) { … }
TEST_F(SandboxedZipAnalyzerTest, InvalidPath) { … }
TEST_F(SandboxedZipAnalyzerTest, NestedEncryptedZip) { … }
TEST_F(SandboxedZipAnalyzerTest, NestedEncryptedRar) { … }