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

  1. Reject the plugin and report it to the hub maintainer - the zip is unsafe.
  2. If you control the zip, repackage it so all entries are relative and contained (no leading '/' or '..').
  3. 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

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


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/97c4303bf334aec7. Report an issue: GitHub.