CherryHQ/cherry-studio · error · Error
Unsafe DXT entry path (zip-slip): ${name}
Error message
Unsafe DXT entry path (zip-slip): ${name} What it means
Thrown by assertZipEntriesWithin() when a DXT or MCPB archive entry name resolves to a path outside the extraction base directory. This is a zip-slip guard: node-stream-zip writes each entry at path.join(baseDir, entry.name) with no built-in containment check, so a crafted entry name like '../../../etc/cron.d/evil' would escape baseDir. Unlike ensurePathWithin, nested subdirectories are allowed (DXT archives legitimately contain them).
Source
Thrown at src/main/ai/mcp/McpPackageService.ts:45
}
return resolvedTarget
}
/**
* Guard against zip-slip: `node-stream-zip` writes each entry at `path.join(baseDir, entry.name)`
* with no containment check, so a name like `../../../foo` would escape `baseDir`. Reject any entry
* whose resolved destination is outside `baseDir` before extraction. Unlike {@link ensurePathWithin},
* nested subdirectories are allowed (a DXT archive legitimately contains them).
*
* @throws Error if any entry name escapes `baseDir`
*/
export function assertZipEntriesWithin(entryNames: string[], baseDir: string): void {
const root = path.resolve(baseDir)
for (const name of entryNames) {
const dest = path.resolve(baseDir, name)
if (dest !== root && !dest.startsWith(root + path.sep)) {
throw new Error(`Unsafe DXT entry path (zip-slip): ${name}`)
}
}
}
interface BaseMcpPackageManifest {
name: string
display_name?: string
version: string
description?: string
long_description?: string
author?: {
name?: string
email?: string
url?: string
}
repository?: {
type?: string
url?: stringView on GitHub (pinned to 726446b54c)
Solutions
- Do not install the archive — it is either malicious or malformed. Report the offending entry name to the package author.
- If building a DXT/MCPB archive, ensure all entry paths are relative and do not contain '..' segments.
- Re-package the archive with a tool that normalizes entry paths (e.g., zip with relative paths only).
Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path'
function isSafeZipEntry(name: string, baseDir: string): boolean {
const root = path.resolve(baseDir)
const dest = path.resolve(baseDir, name)
return dest === root || dest.startsWith(root + path.sep)
}
// Pre-check before calling assertZipEntriesWithin
const unsafe = entryNames.filter(name => !isSafeZipEntry(name, baseDir))
if (unsafe.length > 0) {
logger.error('Refusing to extract archive with unsafe entries', { unsafe })
} Try / catch
try {
assertZipEntriesWithin(Object.keys(await zip.entries()), tempExtractDir)
} catch (error) {
if (error instanceof Error && error.message.includes('zip-slip')) {
logger.error('Refusing to install package — archive contains unsafe entry paths', { error: error.message })
// Clean up the temp extraction directory and abort installation
throw new Error('Package archive is unsafe (zip-slip detected). Do not install.')
}
throw error
} Prevention
- Only install DXT/MCPB packages from trusted sources or verified registries.
- Scan archive entry names before extraction — assertZipEntriesWithin is the guard, but logging the offender helps triage.
- When building archives, use relative paths only and avoid '..' segments in entry names.
When it happens
Trigger: Called from McpPackageService at line 521 after opening a zip and reading its entry list. Every entry name is resolved against baseDir and checked: if the resolved destination is not the root itself and does not start with root + path.sep, the extraction is aborted before any file is written.
Common situations: A malicious DXT/MCPB archive contains entries with '../' sequences designed to overwrite system files or inject code outside the MCP directory; a poorly packaged archive with absolute entry paths (e.g., '/etc/config'); an archive created on Windows with backslash separators that resolve unexpectedly on a Unix host.
Related errors
- Path traversal detected: target path must be direct child of
- Invalid command: path traversal detected in "${command}"
- Invalid args: path traversal detected in argument at index $
- Invalid MCP package upload: file name cannot contain path se
- Access denied: Path is outside the configured workspace root
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/c7c26cb1c66206a2.
Report an issue: GitHub.