feat: SAC 0.7.2 security hardening (rate limit, JWT DB check, DOMPurify)
Path traversal fix in SPA fallback, admin-only host delete, login rate limit with 3 attempts and Telegram alert, JWT validated against active users in DB, and DOMPurify for agent report HTML. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,20 +1,30 @@
|
||||
/** Безопасный вывод HTML из агента (только базовая разметка). */
|
||||
/** Безопасный вывод HTML из агента (DOMPurify, белый список тегов). */
|
||||
import DOMPurify from "dompurify";
|
||||
|
||||
const ALLOWED_REPORT_TAGS = [
|
||||
"b",
|
||||
"strong",
|
||||
"i",
|
||||
"em",
|
||||
"u",
|
||||
"code",
|
||||
"pre",
|
||||
"br",
|
||||
"p",
|
||||
"div",
|
||||
"span",
|
||||
"ul",
|
||||
"ol",
|
||||
"li",
|
||||
"hr",
|
||||
];
|
||||
|
||||
export function sanitizeAgentHtml(html: string): string {
|
||||
const allowed = /^(b|strong|i|em|u|code|pre|br|p|div|span|ul|ol|li|hr)$/i;
|
||||
return html.replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, (tag, name: string) => {
|
||||
if (allowed.test(name)) {
|
||||
if (tag.toLowerCase().startsWith("</")) {
|
||||
return `</${name.toLowerCase()}>`;
|
||||
}
|
||||
if (name.toLowerCase() === "br") {
|
||||
return "<br>";
|
||||
}
|
||||
return `<${name.toLowerCase()}>`;
|
||||
}
|
||||
return "";
|
||||
return DOMPurify.sanitize(html, {
|
||||
ALLOWED_TAGS: ALLOWED_REPORT_TAGS,
|
||||
ALLOWED_ATTR: [],
|
||||
});
|
||||
}
|
||||
|
||||
export interface DailyReportStats {
|
||||
platform?: "ssh" | "windows";
|
||||
successful_logins?: number;
|
||||
|
||||
Reference in New Issue
Block a user