Sanitize email HTML to prevent XSS (#478)

* Sanitize email HTML to prevent XSS

Fixes #457

* Replace dompurify with isomorphic-dompurify as per https://github.com/cure53/DOMPurify/issues/29

* Switch to dompurify and make it work server-side on our own.
This commit is contained in:
Bruno Bernardino 2022-06-22 11:17:40 +01:00 committed by GitHub
parent 63a1a144ad
commit 5273c9b749
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 6721 additions and 6614 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,8 @@
"license": "GPLv3",
"devDependencies": {
"@types/chai": "4.2.18",
"@types/dompurify": "2.3.3",
"@types/jsdom": "16.2.14",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "9.2.2",
@ -31,9 +33,11 @@
"@types/stripe": "8.0.416",
"ansi-colors": "4.1.1",
"date-fns": "2.22.1",
"dompurify": "2.3.8",
"dotenv": "16.0.0",
"fs-extra": "10.0.0",
"geolite2-redist": "2.0.4",
"jsdom": "19.0.0",
"level": "7.0.0",
"maxmind": "4.3.2",
"mixpanel": "0.13.0",

View File

@ -4,6 +4,7 @@ import { Config, ConfigParam } from "@padloc/core/src/config";
import { readFileSync, readdirSync } from "fs";
import { Err, ErrorCode } from "@padloc/core/src/error";
import { resolve } from "path";
import dompurify from "../tools/dompurify";
export class SMTPConfig extends Config {
constructor(init: Partial<SMTPConfig> = {}) {
@ -76,7 +77,7 @@ export class SMTPSender implements Messenger {
}
for (const [name, value] of Object.entries({ title: message.title, ...message.data })) {
html = html.replace(new RegExp(`{{ ?${name} ?}}`, "gi"), value);
html = html.replace(new RegExp(`{{ ?${name} ?}}`, "gi"), dompurify.sanitize(value));
text = text.replace(new RegExp(`{{ ?${name} ?}}`, "gi"), value);
}

View File

@ -0,0 +1,14 @@
import { JSDOM } from "jsdom";
import dompurify from "dompurify";
interface ServerSideDomPurify {
sanitize: (unsafeHtmlInput: string) => string;
}
const serverSideDomPurify = () => {
const { window } = new JSDOM("<!DOCTYPE html>");
// @ts-ignore this is fine
return dompurify(window) as ServerSideDomPurify;
};
export default serverSideDomPurify();