xss-safe-display
Version:
A TypeScript library for safe display and sanitization to prevent XSS attacks.
109 lines (107 loc) • 3.24 kB
JavaScript
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}, "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