Mintplex-Labs/anything-llm · critical · Error
[ImportedPlugin.importCommunityItemFromUrl]: Entry "${entry.
Error message
[ImportedPlugin.importCommunityItemFromUrl]: Entry "${entry.entryName}" would extract outside plugin folder - not allowed. What it means
Thrown in ImportedPlugin.importCommunityItemFromUrl while iterating zip entries before extractAllTo. If any entry's resolved path is not within pluginFolder, extraction is aborted. This is a deliberate Zip Slip (CWE-22) mitigation - a hostile community plugin zip could otherwise write files outside the plugins directory.
Source
Thrown at server/utils/agents/imported.js:333
);
resolve(false);
}
});
const success = await downloadZipFile;
if (!success)
return { success: false, error: "Failed to download zip file." };
// Unzip the file to the plugin folder
// Note: https://github.com/cthackers/adm-zip?tab=readme-ov-file#electron-original-fs
const AdmZip = require("adm-zip");
const zip = new AdmZip(zipFilePath);
// Validate all zip entries to prevent Zip Slip path traversal attacks (CWE-22)
for (const entry of zip.getEntries()) {
const entryPath = path.resolve(pluginFolder, entry.entryName);
if (!isWithin(pluginFolder, entryPath) && pluginFolder !== entryPath) {
throw new Error(
`[ImportedPlugin.importCommunityItemFromUrl]: Entry "${entry.entryName}" would extract outside plugin folder - not allowed.`
);
}
}
zip.extractAllTo(pluginFolder);
// We want to make sure specific keys are set to the proper values for
// plugin.json so we read and overwrite the file with the proper values.
const pluginJsonPath = path.resolve(pluginFolder, "plugin.json");
const pluginJson = safeJsonParse(fs.readFileSync(pluginJsonPath, "utf8"));
pluginJson.active = false;
pluginJson.hubId = hubId;
fs.writeFileSync(pluginJsonPath, JSON.stringify(pluginJson, null, 2));
console.log(
`ImportedPlugin.importCommunityItemFromUrl - successfully imported plugin to agent-skills/${hubId}`
);View on GitHub (pinned to 526360e320)
Solutions
- Reject the plugin and report it to the hub maintainer - the zip is unsafe.
- If you control the zip, repackage it so all entries are relative and contained (no leading '/' or '..').
- Keep this guard; do not bypass it.
Defensive patterns
Strategy: validation
Validate before calling
// defense already lives in the code; at the call site treat a defensive failure as terminal:
const res = await ImportedPlugin.importCommunityItemFromUrl(url);
if (!res.success && /not allowed/.test(res.error)) throw new Error(`Unsafe plugin zip from ${url}`); Try / catch
const res = await ImportedPlugin.importCommunityItemFromUrl(url); if (!res.success && /not allowed/.test(res.error)) return reportUnsafePlugin(url);
Prevention
- Only install community plugins from trusted sources.
- Always validate zip entries before extractAllTo (the code does).
- Prefer strictly relative entry paths in zips you produce.
When it happens
Trigger: importCommunityItemFromUrl downloads a .zip and at least one entry has a name like '../../etc/passwd' or an absolute path, so path.resolve(pluginFolder, entry.entryName) escapes pluginFolder.
Common situations: Installing a crafted/hostile community agent-skill plugin; a zip produced by a tool that stores absolute entry names; a corrupted zip with malformed entry names.
Related errors
- Plugin handler does not pass path validation.
- Invalid path.
- Invalid path name
- Invalid folder name.
- No plugin hubID passed.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/97c4303bf334aec7.
Report an issue: GitHub.