| author | |
| committer | |
| log | 242102f9d113fff321559c8645e79a29f0bdf70d |
| tree | 4c0e5787b20927009789740626d618d12b2bf809 |
| parent | 6de23100352b9c94cc8c92737687091917951df3 |
Previously, when extracting a ZIP file, isBadFilename(), which is
designed to reject ../ patterns to prevent directory traversal, was
called before normalizing backslashes to forward slashes.
This allowed path traversal sequences like ..\\..\\..\\etc\\passwd
which pass validation but are then converted to ../../../etc/passwd
for file extraction.1 files changed, 3 insertions(+), 3 deletions(-)
lib/std/zip.zig+3-3| ... | ... | @@ -536,9 +536,6 @@ pub const Iterator = struct { |
| 536 | 536 | @as(u64, local_header.extra_len); |
| 537 | 537 | }; |
| 538 | 538 | |
| 539 | if (isBadFilename(filename)) | |
| 540 | return error.ZipBadFilename; | |
| 541 | ||
| 542 | 539 | if (options.allow_backslashes) { |
| 543 | 540 | std.mem.replaceScalar(u8, filename, '\\', '/'); |
| 544 | 541 | } else { |
| ... | ... | @@ -546,6 +543,9 @@ pub const Iterator = struct { |
| 546 | 543 | return error.ZipFilenameHasBackslash; |
| 547 | 544 | } |
| 548 | 545 | |
| 546 | if (isBadFilename(filename)) | |
| 547 | return error.ZipBadFilename; | |
| 548 | ||
| 549 | 549 | // All entries that end in '/' are directories |
| 550 | 550 | if (filename[filename.len - 1] == '/') { |
| 551 | 551 | if (self.uncompressed_size != 0) |