From 154f17ab129daab61ed800df6ad9b5a376dfa0a2 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Thu, 2 May 2024 17:20:24 -1000 Subject: [PATCH] refactor(api): :package: Change sanitizer from DOMPurify to xss --- bun.lockb | Bin 142228 -> 142972 bytes database/entities/Status.ts | 4 +- package.json | 4 +- packages/database-interface/note.ts | 3 +- .../v1/accounts/update_credentials/index.ts | 9 +-- server/api/api/v1/statuses/index.test.ts | 58 ++++++++++++++ utils/sanitization.ts | 73 ++++++++---------- 7 files changed, 99 insertions(+), 52 deletions(-) diff --git a/bun.lockb b/bun.lockb index fd3be1f60abb50705086df58c561c77143560b79..2d93ce0fca445e9265c343ca11372da321177976 100755 GIT binary patch delta 24567 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 G+WlYquwRJ) delta 24013 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∨TY0tQ)^5w5h7Q? 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 gnT>do>77S*NpIb1zz@~ diff --git a/database/entities/Status.ts b/database/entities/Status.ts index 4e313c25..9e88a72f 100644 --- a/database/entities/Status.ts +++ b/database/entities/Status.ts @@ -555,14 +555,14 @@ export const contentToHtml = async ( let htmlContent: string; if (content["text/html"]) { - htmlContent = content["text/html"].content; + htmlContent = await sanitizeHtml(content["text/html"].content); } else if (content["text/markdown"]) { htmlContent = await sanitizeHtml( await markdownParse(content["text/markdown"].content), ); } else if (content["text/plain"]?.content) { // Split by newline and add

tags - htmlContent = content["text/plain"].content + htmlContent = (await sanitizeHtml(content["text/plain"].content)) .split("\n") .map((line) => `

${line}

`) .join("\n"); diff --git a/package.json b/package.json index 68f27d9b..a7e1a481 100644 --- a/package.json +++ b/package.json @@ -77,10 +77,8 @@ "cli-parser": "workspace:*", "cli-table": "^0.3.11", "config-manager": "workspace:*", - "dompurify": "^3.1.2", "drizzle-orm": "^0.30.7", "extract-zip": "^2.0.1", - "happy-dom": "14.7.1", "html-to-text": "^9.0.5", "ioredis": "^5.3.2", "ip-matching": "^2.1.2", @@ -103,6 +101,8 @@ "request-parser": "workspace:*", "sharp": "^0.33.3", "string-comparison": "^1.3.0", + "stringify-entities": "^4.0.4", + "xss": "^1.0.15", "zod": "^3.22.4", "zod-validation-error": "^3.2.0" } diff --git a/packages/database-interface/note.ts b/packages/database-interface/note.ts index 13f060f8..adcabfaa 100644 --- a/packages/database-interface/note.ts +++ b/packages/database-interface/note.ts @@ -45,6 +45,7 @@ import { config } from "~packages/config-manager"; import type { Attachment as APIAttachment } from "~types/mastodon/attachment"; import type { Status as APIStatus } from "~types/mastodon/status"; import { User } from "./user"; +import { sanitizedHtmlStrip } from "@sanitization"; /** * Gives helpers to fetch notes from database in a nice format @@ -208,7 +209,7 @@ export class Note { contentType: "text/html", visibility, sensitive: is_sensitive, - spoilerText: spoiler_text, + spoilerText: await sanitizedHtmlStrip(spoiler_text), uri: uri || null, replyId: replyId ?? null, quotingId: quoteId ?? null, diff --git a/server/api/api/v1/accounts/update_credentials/index.ts b/server/api/api/v1/accounts/update_credentials/index.ts index e0065908..cdb000ed 100644 --- a/server/api/api/v1/accounts/update_credentials/index.ts +++ b/server/api/api/v1/accounts/update_credentials/index.ts @@ -1,6 +1,6 @@ import { apiRoute, applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; -import { sanitizeHtml } from "@sanitization"; +import { sanitizeHtml, sanitizedHtmlStrip } from "@sanitization"; import { config } from "config-manager"; import { and, eq } from "drizzle-orm"; import ISO6391 from "iso-639-1"; @@ -97,10 +97,9 @@ export default apiRoute( const sanitizedNote = await sanitizeHtml(note ?? ""); - const sanitizedDisplayName = await sanitizeHtml(display_name ?? "", { - ALLOWED_TAGS: [], - ALLOWED_ATTR: [], - }); + const sanitizedDisplayName = await sanitizedHtmlStrip( + display_name ?? "", + ); let mediaManager: MediaBackend; diff --git a/server/api/api/v1/statuses/index.test.ts b/server/api/api/v1/statuses/index.test.ts index 621734a2..a73c855c 100644 --- a/server/api/api/v1/statuses/index.test.ts +++ b/server/api/api/v1/statuses/index.test.ts @@ -361,4 +361,62 @@ describe(meta.route, () => { }); }); }); + + describe("HTML injection testing", () => { + test("should not allow HTML injection", async () => { + const response = await sendTestRequest( + new Request(new URL(meta.route, config.http.base_url), { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${tokens[0].accessToken}`, + }, + body: JSON.stringify({ + status: "Hi! ", + federate: false, + }), + }), + ); + + expect(response.status).toBe(200); + expect(response.headers.get("content-type")).toBe( + "application/json", + ); + + const object = (await response.json()) as APIStatus; + + expect(object.content).toBe( + "

Hi! <script>alert('Hello, world!');</script>

", + ); + }); + + test("should not allow HTML injection in spoiler_text", async () => { + const response = await sendTestRequest( + new Request(new URL(meta.route, config.http.base_url), { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${tokens[0].accessToken}`, + }, + body: JSON.stringify({ + status: "Hello, world!", + spoiler_text: + "uwu ", + federate: false, + }), + }), + ); + + expect(response.status).toBe(200); + expect(response.headers.get("content-type")).toBe( + "application/json", + ); + + const object = (await response.json()) as APIStatus; + + expect(object.spoiler_text).toBe( + "uwu <script>alert('Hello, world!');</script>", + ); + }); + }); }); diff --git a/utils/sanitization.ts b/utils/sanitization.ts index 46e0db28..9e8486b3 100644 --- a/utils/sanitization.ts +++ b/utils/sanitization.ts @@ -1,52 +1,41 @@ -import { config } from "config-manager"; -import DOMPurify from "dompurify"; -import { GlobalWindow } from "happy-dom"; +import xss, { type IFilterXSSOptions } from "xss"; +import { stringifyEntitiesLight } from "stringify-entities"; -const window = new GlobalWindow(); +export const sanitizedHtmlStrip = (html: string) => { + return sanitizeHtml(html, { + whiteList: {}, + }); +}; export const sanitizeHtml = async ( html: string, - extraConfig?: DOMPurify.Config, + extraConfig?: IFilterXSSOptions, ) => { - // @ts-expect-error Types clash but it works i swear - const sanitizedHtml = DOMPurify(window).sanitize(html, { - ALLOWED_TAGS: [ - "a", - "p", - "br", - "b", - "i", - "em", - "strong", - "del", - "code", - "u", - "pre", - "ul", - "ol", - "li", - "blockquote", - ], - ALLOWED_ATTR: [ - "href", - "target", - "title", - "rel", - "class", - "start", - "reversed", - "value", - ], - ALLOWED_URI_REGEXP: new RegExp( - `/^(?:(?:${config.validation.url_scheme_whitelist.join( - "|", - )}):|[^a-z]|[a-z+.-]+(?:[^a-z+.-:]|$))/i`, - ), - USE_PROFILES: { - mathMl: true, + const sanitizedHtml = xss(html, { + whiteList: { + a: ["href", "title", "target", "rel", "class"], + p: ["class"], + br: ["class"], + b: ["class"], + i: ["class"], + em: ["class"], + strong: ["class"], + del: ["class"], + code: ["class"], + u: ["class"], + pre: ["class"], + ul: ["class"], + ol: ["class"], + li: ["class"], + blockquote: ["class"], }, + stripIgnoreTag: false, + escapeHtml: (unsafeHtml) => + stringifyEntitiesLight(unsafeHtml, { + escapeOnly: true, + }), ...extraConfig, - }) as string; + }); // Check text to only allow h-*, p-*, u-*, dt-*, e-*, mention, hashtag, ellipsis, invisible classes const allowedClasses = [