fix(frontend/mcp): Loop HTML tag stripping to prevent XSS bypass

The single-pass regex `/<[^>]+>/g` can be bypassed with nested tags
like `<scr<script>ipt>`. Loop until no more tags are found.
Note: React auto-escapes JSX so this is defense-in-depth.
This commit is contained in:
Zamil Majdy
2026-02-09 19:10:17 +04:00
parent fe70b6929f
commit d9269310cc

View File

@@ -39,7 +39,6 @@ type DialogStep = "url" | "tool";
const OAUTH_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
export function MCPToolDialog({
open,
onClose,
@@ -526,11 +525,15 @@ function MCPToolCard({
const required = new Set<string>(tool.input_schema?.required ?? []);
const paramNames = Object.keys(properties);
// Strip XML-like tags and hints from description for cleaner display
const cleanDescription = (tool.description ?? "")
.replace(/<[^>]+>[^<]*<\/[^>]+>/g, "")
.replace(/<[^>]+>/g, "")
.trim();
// Strip XML-like tags from description for cleaner display.
// Loop to handle nested tags like <scr<script>ipt> (CodeQL fix).
let cleanDescription = tool.description ?? "";
let prev = "";
while (prev !== cleanDescription) {
prev = cleanDescription;
cleanDescription = cleanDescription.replace(/<[^>]*>/g, "");
}
cleanDescription = cleanDescription.trim();
return (
<button