UNPKG

xss-safe-display

Version:

A TypeScript library for safe display and sanitization to prevent XSS attacks.

109 lines (107 loc) 3.24 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/xssGuard.ts import DOMPurify from "dompurify"; var sanitizeString = /* @__PURE__ */ __name((value) => { if (!value) return ""; try { return DOMPurify.sanitize(value, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] }); } catch (error) { console.error("XSS sanitize error:", error); return value.replace(/<[^>]*>/g, ""); } }, "sanitizeString"); var sanitizeHTML = /* @__PURE__ */ __name((html, allowedTags = ["b", "i", "u", "p", "span", "br"]) => { if (!html) return ""; try { return DOMPurify.sanitize(html, { ALLOWED_TAGS: allowedTags, ALLOWED_ATTR: ["class", "style"] }); } catch (error) { console.error("HTML sanitize error:", error); return sanitizeString(html); } }, "sanitizeHTML"); var sanitizeObject = /* @__PURE__ */ __name((obj) => { if (!obj || typeof obj !== "object") return obj; if (Array.isArray(obj)) { return obj.map((item) => { if (typeof item === "string") { if (/<script\b[^>]*>(.*?)<\/script>/gi.test(item)) { return ""; } return item.replace(/<[^>]*>/g, ""); } if (item && typeof item === "object") { return sanitizeObject(item); } return item; }); } return Object.fromEntries( Object.entries(obj).map(([key, value]) => { if (typeof value === "string") { if (/<script\b[^>]*>(.*?)<\/script>/gi.test(value)) { return [key, ""]; } return [key, value.replace(/<[^>]*>/g, "")]; } if (value && typeof value === "object") { return [key, sanitizeObject(value)]; } return [key, value]; }) ); }, "sanitizeObject"); var escapeHTML = /* @__PURE__ */ __name((text) => { if (!text) return ""; return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"); }, "escapeHTML"); var sanitizeUrl = /* @__PURE__ */ __name((url) => { if (!url) return "#"; const trimmed = String(url).trim(); const lower = trimmed.toLowerCase(); if (/^(javascript|data|vbscript):/.test(lower)) { return "#"; } if (trimmed.startsWith("/") || trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed.startsWith("#")) { return trimmed; } if (lower.startsWith("mailto:")) { return trimmed; } if (lower.startsWith("http://") || lower.startsWith("https://")) { return trimmed; } if (/^[\w-]+(\.[\w-]+)+([\/?#].*)?$/.test(trimmed)) { return `https://${trimmed}`; } return "#"; }, "sanitizeUrl"); // src/index.ts var safeDisplay = { text: /* @__PURE__ */ __name((value) => { if (value === void 0 || value === null) return ""; const textValue = String(value); return escapeHTML(textValue); }, "text"), html: /* @__PURE__ */ __name((content, allowedTags) => { return { __html: sanitizeHTML(content, allowedTags) }; }, "html"), url: /* @__PURE__ */ __name((url) => { return sanitizeUrl(url); }, "url") }; export { escapeHTML, safeDisplay, sanitizeHTML, sanitizeObject, sanitizeString, sanitizeUrl }; //# sourceMappingURL=index.mjs.map