{"record":{"id":"36831b25969a510e","repo":"ComposioHQ/composio","slug":"unsafezipentryerror-entry-filename","errorCode":null,"errorMessage":"UnsafeZipEntryError: ${entry.fileName}","messagePattern":"UnsafeZipEntryError: (.+?)","errorType":"exception","errorClass":"UnsafeZipEntryError","httpStatus":null,"severity":"error","filePath":"ts/packages/cli/src/utils/extract-zip-safely.ts","lineNumber":58,"sourceCode":"    this.name = 'UnsafeZipEntryError';\n  }\n}\n\n/**\n * Whether a zip entry's external attributes describe a symbolic link.\n *\n * Archives written on Windows leave the Unix mode bits empty, which reads as a\n * regular file — the correct answer, since such an archive has no symlinks.\n */\nexport const isSymlinkZipEntry = (externalFileAttributes: number): boolean =>\n  ((externalFileAttributes >>> UNIX_MODE_SHIFT) & FILE_TYPE_MASK) === SYMLINK_FILE_TYPE;\n\nexport const extractZipSafely = (zipPath: string, dir: string): Promise<void> =>\n  extractZip(zipPath, {\n    dir,\n    onEntry: entry => {\n      if (isSymlinkZipEntry(entry.externalFileAttributes)) {\n        throw new UnsafeZipEntryError(entry.fileName);\n      }\n    },\n  });\n","sourceCodeStart":40,"sourceCodeEnd":62,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/cli/src/utils/extract-zip-safely.ts#L40-L62","documentation":"extractZipSafely refuses to extract a zip entry whose external file attributes mark it as a symlink. Symlinks in archives are a classic zip-slip / arbitrary-write vector, so extraction is aborted with UnsafeZipEntryError for that entry's fileName.","triggerScenarios":"Calling extractZipSafely on an archive that contains at least one symlink entry (Unix mode bits set in externalFileAttributes).","commonSituations":"Extracting downloaded CLI release archives, third-party zips, or artifacts packed on macOS/Linux tools that store symlinks; supply-chain or security-hardened extraction.","solutions":["Re-package the archive without symlinks (dereference them before zipping)","Extract with a different tool if the symlinks are trusted and intentional","Inspect the zip (e.g. unzip -l / zipinfo) to identify the offending entry"],"exampleFix":"// before\nzip -ry out.zip dir/; // stores symlinks\n// after\nzip -r out.zip dir/; // dereferences symlinks into real files","handlingStrategy":"validation","validationCode":"// Pre-scan entries before extracting\nconst list = await yauzl/yauzl-based scan; // reject symlink entries (mode & 0xF000 === 0xA000)","typeGuard":"const isSymlink = (attrs: number) => (attrs >>> 16 & 0xF000) === 0xA000;","tryCatchPattern":"catch (e) { if (e instanceof UnsafeZipEntryError) { /* quarantine archive */ } else throw e; }","preventionTips":["Only extract archives from trusted sources","Scan zips for symlink entries before extraction"],"tags":["security","zip","extraction","typescript"],"backgroundTag":"unsafe-archive-entry","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}