mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
fix(import): count every zip record against the entry cap
index.size undercounted it: directory records return before the check, and a repeated filename overwrites the same map key. Either lets an archive carry far more records than the cap allows, each costing real central-directory traversal, while the limit believes the archive is nearly empty.
This commit is contained in:
parent
f9d0c5fbb4
commit
fc57538611
1 changed files with 12 additions and 5 deletions
|
|
@ -128,8 +128,20 @@ function indexEntries(
|
|||
return new Promise((resolve, reject) => {
|
||||
const index = new Map<string, yauzl.Entry>();
|
||||
let total = 0;
|
||||
/** Counted per record, not per indexed entry. `index.size` undercounts:
|
||||
* directory records return before it is ever consulted, and a repeated
|
||||
* filename overwrites the same key. Either lets an archive hold millions
|
||||
* of records that cost real central-directory traversal while the cap
|
||||
* believes it is nearly empty. */
|
||||
let records = 0;
|
||||
|
||||
zipfile.on('entry', (entry: yauzl.Entry) => {
|
||||
records += 1;
|
||||
if (records > options.maxEntries) {
|
||||
reject(new ZipBombError(`Archive exceeds ${options.maxEntries} entries`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (/\/$/.test(entry.fileName)) {
|
||||
zipfile.readEntry();
|
||||
return;
|
||||
|
|
@ -142,11 +154,6 @@ function indexEntries(
|
|||
return;
|
||||
}
|
||||
|
||||
if (index.size + 1 > options.maxEntries) {
|
||||
reject(new ZipBombError(`Archive exceeds ${options.maxEntries} entries`));
|
||||
return;
|
||||
}
|
||||
|
||||
/** Cheap early reject from the central directory's declared sizes.
|
||||
* This field is attacker-controlled and not trusted on its own —
|
||||
* `ArchiveTotals` re-checks the real, streamed byte count on every
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue