mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 07:05:24 +00:00
fix: harden the plugin runtime after the 2.9.0 security review
This commit is contained in:
1 parent
2961297989
commit
c6a44b7ff3
69 files changed
+4613
-312
No files matched your search
@@ -16,7 +16,7 @@
|
||||
|
||||
import express, { type Request, type Response } from "express";
|
||||
import { databaseLogger } from "../../utils/logger.js";
|
||||
import { getPluginRouter } from "../../plugins/http.js";
|
||||
import { getPluginRouter, isPluginInstalled } from "../../plugins/http.js";
|
||||
import { getRequestBasePath } from "../../utils/request-origin.js";
|
||||
import type { PluginLegacyRedirect } from "@termix/plugin-sdk/manifest";
|
||||
|
||||
@@ -51,7 +51,7 @@ const router = express.Router();
|
||||
* 401:
|
||||
* description: Authentication required.
|
||||
* 404:
|
||||
* description: Plugin not installed or serves no routes.
|
||||
* description: No plugin with this id is installed.
|
||||
* 503:
|
||||
* description: Plugin is installed but not running.
|
||||
*/
|
||||
@@ -60,17 +60,26 @@ router.use("/:pluginId", (req: Request, res: Response, next) => {
|
||||
const pluginRouter = getPluginRouter(pluginId);
|
||||
|
||||
if (!pluginRouter) {
|
||||
databaseLogger.warn("Plugin API request for unregistered plugin", {
|
||||
operation: "plugin_api_dispatch",
|
||||
pluginId,
|
||||
});
|
||||
res.status(404).json({ error: "Plugin not installed or not running" });
|
||||
notServing(res, pluginId);
|
||||
return;
|
||||
}
|
||||
|
||||
pluginRouter(req, res, next);
|
||||
});
|
||||
|
||||
/** 503 for an installed plugin that is off, 404 for an unknown id. */
|
||||
function notServing(res: Response, pluginId: string): void {
|
||||
if (isPluginInstalled(pluginId)) {
|
||||
res.status(503).json({ error: "Plugin is not running", pluginId });
|
||||
return;
|
||||
}
|
||||
databaseLogger.warn("Plugin API request for unregistered plugin", {
|
||||
operation: "plugin_api_dispatch",
|
||||
pluginId,
|
||||
});
|
||||
res.status(404).json({ error: "Plugin not installed" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts the dispatcher. No auth in front of it: each plugin router runs
|
||||
* core auth itself and skips it only for the paths it declared public, so a
|
||||
@@ -120,7 +129,7 @@ export function mountPluginLegacyPaths(
|
||||
if (!plugin.legacyPaths.some((path) => under(req.path, path))) continue;
|
||||
const pluginRouter = getPluginRouter(plugin.id);
|
||||
if (!pluginRouter) {
|
||||
res.status(404).json({ error: "Plugin not installed or not running" });
|
||||
notServing(res, plugin.id);
|
||||
return;
|
||||
}
|
||||
req.url = req.url.slice(plugin.id.length + 1) || "/";
|
||||
|
||||
Reference in new issue
Block a user