fix: critical security issues - webhook bypass, SSRF, XSS

This commit is contained in:
openclawd 2026-02-14 16:19:48 +00:00
parent bba19442f4
commit 6a38ba4adc
2 changed files with 49 additions and 13 deletions

View file

@ -1,6 +1,24 @@
import { Router, Request, Response } from "express";
import { renderPdf, renderUrlPdf } from "../services/browser.js";
import { markdownToHtml, wrapHtml } from "../services/markdown.js";
import dns from "node:dns/promises";
import net from "node:net";
function isPrivateIP(ip: string): boolean {
// IPv6 loopback/unspecified
if (ip === "::1" || ip === "::") return true;
// IPv4-mapped IPv6
if (ip.startsWith("::ffff:")) ip = ip.slice(7);
if (!net.isIPv4(ip)) return false;
const parts = ip.split(".").map(Number);
if (parts[0] === 0) return true; // 0.0.0.0/8
if (parts[0] === 10) return true; // 10.0.0.0/8
if (parts[0] === 127) return true; // 127.0.0.0/8
if (parts[0] === 169 && parts[1] === 254) return true; // 169.254.0.0/16
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true; // 172.16.0.0/12
if (parts[0] === 192 && parts[1] === 168) return true; // 192.168.0.0/16
return false;
}
export const convertRouter = Router();
@ -93,9 +111,10 @@ convertRouter.post("/url", async (req: Request, res: Response) => {
return;
}
// Basic URL validation
// URL validation + SSRF protection
let parsed: URL;
try {
const parsed = new URL(body.url);
parsed = new URL(body.url);
if (!["http:", "https:"].includes(parsed.protocol)) {
res.status(400).json({ error: "Only http/https URLs are supported" });
return;
@ -105,6 +124,18 @@ convertRouter.post("/url", async (req: Request, res: Response) => {
return;
}
// DNS lookup to block private/reserved IPs
try {
const { address } = await dns.lookup(parsed.hostname);
if (isPrivateIP(address)) {
res.status(400).json({ error: "URL resolves to private/reserved IP" });
return;
}
} catch {
res.status(400).json({ error: "DNS lookup failed for URL hostname" });
return;
}
const pdf = await renderUrlPdf(body.url, {
format: body.format,
landscape: body.landscape,