From f677737fdd03108415310657ac2e30d7c4a6b2b4 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Mon, 16 Oct 2023 12:03:29 -1000 Subject: [PATCH] Add sanitization to HTML --- bun.lockb | Bin 233994 -> 250775 bytes database/entities/User.ts | 3 +- package.json | 2 + .../v1/accounts/update_credentials/index.ts | 32 +++++--- server/api/api/v1/statuses/index.ts | 8 +- utils/config.ts | 2 +- utils/sanitization.ts | 76 ++++++++++++++++++ 7 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 utils/sanitization.ts diff --git a/bun.lockb b/bun.lockb index 901f0977214069c13bd4d39a07a67964424a7c0b..1e191d276ead490832a88a092a063c2b0aab44b5 100755 GIT binary patch delta 53441 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 delta 44075 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 diff --git a/database/entities/User.ts b/database/entities/User.ts index ed245970..26dc308b 100644 --- a/database/entities/User.ts +++ b/database/entities/User.ts @@ -263,8 +263,8 @@ export class User extends BaseEntity { await user.generateKeys(); await user.updateActor(); - await user.save(); + return user; } @@ -403,6 +403,7 @@ export class User extends BaseEntity { outbox: `${config.http.base_url}/users/${this.username}/outbox`, followers: `${config.http.base_url}/users/${this.username}/followers`, following: `${config.http.base_url}/users/${this.username}/following`, + published: new Date(this.created_at).toISOString(), manuallyApprovesFollowers: false, summary: this.note, icon: { diff --git a/package.json b/package.json index 7ef5c4cd..02f0acdc 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,9 @@ }, "dependencies": { "ip-matching": "^2.1.2", + "isomorphic-dompurify": "^1.9.0", "jsonld": "^8.3.1", + "marked": "^9.1.2", "pg": "^8.11.3", "reflect-metadata": "^0.1.13", "typeorm": "^0.3.17" diff --git a/server/api/api/v1/accounts/update_credentials/index.ts b/server/api/api/v1/accounts/update_credentials/index.ts index ffcdc0d2..14339ab5 100644 --- a/server/api/api/v1/accounts/update_credentials/index.ts +++ b/server/api/api/v1/accounts/update_credentials/index.ts @@ -3,6 +3,8 @@ import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; import { User } from "~database/entities/User"; import { applyConfig } from "@api"; +import { sanitize } from "isomorphic-dompurify"; +import { sanitizeHtml } from "@sanitization"; export const meta = applyConfig({ allowedMethods: ["PATCH"], @@ -50,11 +52,18 @@ export default async (req: Request): Promise => { "source[language]": string; }>(req); + const sanitizedNote = await sanitizeHtml(note ?? ""); + + const sanitizedDisplayName = sanitize(display_name, { + ALLOWED_TAGS: [], + ALLOWED_ATTR: [], + }); + if (display_name) { // Check if within allowed display name lengths if ( - display_name.length < 3 || - display_name.length > config.validation.max_displayname_size + sanitizedDisplayName.length < 3 || + sanitizedDisplayName.length > config.validation.max_displayname_size ) { return errorResponse( `Display name must be between 3 and ${config.validation.max_displayname_size} characters`, @@ -65,19 +74,19 @@ export default async (req: Request): Promise => { // Check if display name doesnt match filters if ( config.filters.displayname_filters.some(filter => - display_name.match(filter) + sanitizedDisplayName.match(filter) ) ) { return errorResponse("Display name contains blocked words", 422); } - user.actor.data.name = display_name; - user.display_name = display_name; + user.actor.data.name = sanitizedDisplayName; + user.display_name = sanitizedDisplayName; } if (note) { // Check if within allowed note length - if (note.length > config.validation.max_note_size) { + if (sanitizedNote.length > config.validation.max_note_size) { return errorResponse( `Note must be less than ${config.validation.max_note_size} characters`, 422 @@ -85,12 +94,16 @@ export default async (req: Request): Promise => { } // Check if bio doesnt match filters - if (config.filters.bio_filters.some(filter => note.match(filter))) { + if ( + config.filters.bio_filters.some(filter => + sanitizedNote.match(filter) + ) + ) { return errorResponse("Bio contains blocked words", 422); } - user.actor.data.summary = note; - user.note = note; + user.actor.data.summary = sanitizedNote; + user.note = sanitizedNote; } if (source_privacy) { @@ -177,6 +190,7 @@ export default async (req: Request): Promise => { } await user.save(); + await user.updateActor(); return jsonResponse(await user.toAPI()); }; diff --git a/server/api/api/v1/statuses/index.ts b/server/api/api/v1/statuses/index.ts index f8fe63c9..ba2e7a53 100644 --- a/server/api/api/v1/statuses/index.ts +++ b/server/api/api/v1/statuses/index.ts @@ -5,7 +5,9 @@ import { applyConfig } from "@api"; import { getConfig } from "@config"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; +import { sanitizeHtml } from "@sanitization"; import { APActor } from "activitypub-types"; +import { sanitize } from "isomorphic-dompurify"; import { Application } from "~database/entities/Application"; import { RawObject } from "~database/entities/RawObject"; import { Status } from "~database/entities/Status"; @@ -72,7 +74,9 @@ export default async (req: Request): Promise => { return errorResponse("Status is required", 422); } - if (status.length > config.validation.max_note_size) { + const sanitizedStatus = await sanitizeHtml(status); + + if (sanitizedStatus.length > config.validation.max_note_size) { return errorResponse( `Status must be less than ${config.validation.max_note_size} characters`, 400 @@ -134,7 +138,7 @@ export default async (req: Request): Promise => { const newStatus = await Status.createNew({ account: user, application, - content: status, + content: sanitizedStatus, visibility: visibility || (config.defaults.visibility as diff --git a/utils/config.ts b/utils/config.ts index 8ab1d030..fb46f025 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -91,7 +91,7 @@ export const configDefaults: ConfigType = { http: { bind: "http://0.0.0.0", bind_port: "8000", - base_url: "http://fediproject.localhost:8000", + base_url: "http://lysand.localhost:8000", banned_ips: [], }, database: { diff --git a/utils/sanitization.ts b/utils/sanitization.ts new file mode 100644 index 00000000..7512a063 --- /dev/null +++ b/utils/sanitization.ts @@ -0,0 +1,76 @@ +import { getConfig } from "@config"; +import { sanitize } from "isomorphic-dompurify"; + +export const sanitizeHtml = async (html: string) => { + const config = getConfig(); + + const sanitizedHtml = 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, + }, + }); + + // Check text to only allow h-*, p-*, u-*, dt-*, e-*, mention, hashtag, ellipsis, invisible classes + const allowedClasses = [ + "h-", + "p-", + "u-", + "dt-", + "e-", + "mention", + "hashtag", + "ellipsis", + "invisible", + ]; + + return await new HTMLRewriter() + .on("*[class]", { + element(element) { + const classes = element.getAttribute("class")?.split(" ") ?? []; + + classes.forEach(className => { + if ( + !allowedClasses.some(allowedClass => + className.startsWith(allowedClass) + ) + ) { + element.removeAttribute("class"); + } + }); + }, + }) + .transform(new Response(sanitizedHtml)) + .text(); +};