Skip to content

Commit fa14efb

Browse files
committed
Handle zipbomb files
1 parent c510162 commit fa14efb

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

third-party/libscan/libscan/arc/arc.c

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <openssl/evp.h>
88
#include <pcre.h>
99

10+
#define MAX_DECOMPRESSED_SIZE_RATIO 40.0
1011

1112
int should_parse_filtered_file(const char *filepath, int ext) {
1213
char tmp[PATH_MAX * 2];
@@ -206,6 +207,13 @@ scan_code_t parse_archive(scan_arc_ctx_t *ctx, vfile_t *f, document_t *doc, pcre
206207

207208
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
208209
sub_job->vfile.info = *archive_entry_stat(entry);
210+
211+
double decompressed_size_ratio = (double) sub_job->vfile.info.st_size / (double) f->info.st_size;
212+
if (decompressed_size_ratio > MAX_DECOMPRESSED_SIZE_RATIO) {
213+
CTX_LOG_DEBUGF("arc.c", "Skipped %s, possible zip bomb (decompressed_size_ratio=%f)", sub_job->filepath, decompressed_size_ratio)
214+
continue;
215+
}
216+
209217
if (S_ISREG(sub_job->vfile.info.st_mode)) {
210218

211219
const char *utf8_name = archive_entry_pathname_utf8(entry);

third-party/libscan/test/main.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern "C" {
1919
static scan_arc_ctx_t arc_recurse_media_ctx;
2020
static scan_arc_ctx_t arc_list_ctx;
2121
static scan_arc_ctx_t arc_recurse_ooxml_ctx;
22+
static scan_arc_ctx_t arc_recurse_noop_ctx;
2223

2324
static scan_text_ctx_t text_500_ctx;
2425

@@ -58,6 +59,12 @@ void _parse_ooxml(parse_job_t *job) {
5859
parse_ooxml(&ooxml_500_ctx, &job->vfile, &LastSubDoc);
5960
}
6061

62+
void _parse_noop(parse_job_t *job) {
63+
char buf[1024];
64+
65+
while (job->vfile.read(&job->vfile, buf, sizeof(buf)) != 0) {}
66+
}
67+
6168

6269
/* Text */
6370

@@ -752,6 +759,16 @@ TEST(Mobi, Azw3) {
752759
}
753760

754761
/* Arc */
762+
TEST(Arc, ZipBomp) {
763+
vfile_t f;
764+
document_t doc;
765+
load_doc_file("libscan-test-files/test_files/arc/bomb.zip", &f, &doc);
766+
767+
parse_archive(&arc_recurse_noop_ctx, &f, &doc, nullptr, nullptr);
768+
769+
cleanup(&doc, &f);
770+
}
771+
755772
TEST(Arc, Utf8) {
756773
vfile_t f;
757774
document_t doc;
@@ -1096,6 +1113,12 @@ int main(int argc, char **argv) {
10961113
arc_recurse_ooxml_ctx.mode = ARC_MODE_RECURSE;
10971114
arc_recurse_ooxml_ctx.parse = _parse_ooxml;
10981115

1116+
arc_recurse_noop_ctx.log = noop_log;
1117+
arc_recurse_noop_ctx.logf = noop_logf;
1118+
arc_recurse_noop_ctx.store = counter_store;
1119+
arc_recurse_noop_ctx.mode = ARC_MODE_RECURSE;
1120+
arc_recurse_noop_ctx.parse = _parse_noop;
1121+
10991122
arc_list_ctx.log = noop_log;
11001123
arc_list_ctx.logf = noop_logf;
11011124
arc_list_ctx.store = counter_store;

0 commit comments

Comments
 (0)