Mintplex-Labs/anything-llm · error · Error

Plugin handler does not pass path validation.

Error message

Plugin handler does not pass path validation.

What it means

Thrown in the ImportedPlugin constructor (server/utils/agents/imported.js:20) when the resolved handler.js location is not within the plugins/agent-skills directory (isWithin returns false). It is a path-traversal guard (CWE-22) that runs after normalizePath on config.hubId, blocking hubIds containing '..' or absolute paths from escaping the plugin sandbox before the require() call.

Source

Thrown at server/utils/agents/imported.js:21

const { safeJsonParse } = require("../http");
const { isWithin, normalizePath } = require("../files");
const { CollectorApi } = require("../collectorApi");
const pluginsPath =
  process.env.NODE_ENV === "development"
    ? path.resolve(__dirname, "../../storage/plugins/agent-skills")
    : path.resolve(process.env.STORAGE_DIR, "plugins", "agent-skills");
const sharedWebScraper = new CollectorApi();

class ImportedPlugin {
  constructor(config) {
    this.config = config;
    this.handlerLocation = path.resolve(
      pluginsPath,
      normalizePath(this.config.hubId),
      "handler.js"
    );
    if (!isWithin(pluginsPath, this.handlerLocation))
      throw new Error("Plugin handler does not pass path validation.");
    delete require.cache[require.resolve(this.handlerLocation)];
    this.handler = require(this.handlerLocation);
    this.name = config.hubId;
    this.startupConfig = {
      params: {},
    };
  }

  /**
   * Gets the imported plugin handler.
   * @param {string} hubId - The hub ID of the plugin.
   * @returns {ImportedPlugin} - The plugin handler.
   */
  static loadPluginByHubId(hubId) {
    const configLocation = path.resolve(
      pluginsPath,
      normalizePath(hubId),
      "plugin.json"

View on GitHub (pinned to 526360e320)

Solutions

  1. Sanitize hubId to a single safe folder name (e.g. ^[a-z0-9-_]+$) before constructing the plugin.
  2. Regenerate the offending plugin's plugin.json with a clean hubId, or delete and re-import it.
  3. Confirm STORAGE_DIR is set correctly so pluginsPath resolves to the intended directory.

Example fix

// before
const plugin = new ImportedPlugin({ hubId: req.body.hubId });
// after
if (!/^[a-z0-9-_]+$/i.test(req.body.hubId)) return res.status(400).send('invalid hubId');
const plugin = new ImportedPlugin({ hubId: req.body.hubId });
Defensive patterns

Strategy: validation

Validate before calling

function safeHubId(hubId) {
  return typeof hubId === 'string' && /^[a-z0-9-_]+$/i.test(hubId) && !hubId.includes('..');
}
if (!safeHubId(config.hubId)) throw new Error('Invalid hubId');

Try / catch

try { const p = new ImportedPlugin(config); } catch (e) { if (/path validation/.test(e.message)) return rejectPlugin('unsafe hubId'); throw e; }

Prevention

When it happens

Trigger: new ImportedPlugin(config) or ImportedPlugin.loadPluginByHubId(hubId) with a hubId containing traversal sequences ('..'), an absolute path, or a symlink that resolves outside pluginsPath.

Common situations: Corrupted/tampered plugin.json with a malicious hubId; manually renamed plugin folders; a community plugin whose hubId was crafted; STORAGE_DIR mis-set so even valid hubIds resolve outside the expected directory.

Related errors


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