From 60bd43489611df7e8acf884bce0cfd65d70e21d3 Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Mon, 3 Feb 2025 20:00:03 +0530 Subject: [PATCH] Escape HTML in email templates --- .pnp.cjs | 1 + ...t-darwin-arm64-npm-2.1.1-7f6025512f-10.zip | Bin 8406 -> 0 bytes .yarn/cache/fsevents-patch-19706e7e35-10.zip | Bin 23750 -> 0 bytes .../Email/daily-analytics-report.html.ts | 3 +- ...offline-subscription-token-created.html.ts | 4 ++- ...ed-subscription-invitation-created.html.ts | 4 ++- .../Domain/Email/user-email-changed.html.ts | 4 ++- .../user-invited-to-shared-vault.html.ts | 4 ++- .../src/Domain/Email/user-signed-in.html.ts | 4 ++- .../common/src/Domain/Html/SafeHtml.spec.ts | 16 +++++++++ packages/common/src/Domain/Html/SafeHtml.ts | 32 ++++++++++++++++++ packages/common/src/Domain/index.ts | 1 + packages/scheduler/package.json | 1 + .../Email/encourage-email-backups.html.ts | 4 ++- .../encourage-subscription-purchasing.html.ts | 4 ++- .../src/Domain/Email/exit-interview.html.ts | 4 ++- .../Email/dropbox-backup-failed.html.ts | 4 ++- .../email-backup-attachment-created.html.ts | 4 ++- .../Email/google-drive-backup-failed.html.ts | 4 ++- .../Email/one-drive-backup-failed.html.ts | 4 ++- yarn.lock | 1 + 21 files changed, 90 insertions(+), 13 deletions(-) delete mode 100644 .yarn/cache/@cbor-extract-cbor-extract-darwin-arm64-npm-2.1.1-7f6025512f-10.zip delete mode 100644 .yarn/cache/fsevents-patch-19706e7e35-10.zip create mode 100644 packages/common/src/Domain/Html/SafeHtml.spec.ts create mode 100644 packages/common/src/Domain/Html/SafeHtml.ts diff --git a/.pnp.cjs b/.pnp.cjs index 57b64b29e..1448be776 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -6817,6 +6817,7 @@ const RAW_RUNTIME_STATE = ["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\ ["@aws-sdk/client-sns", "npm:3.484.0"],\ ["@aws-sdk/client-sqs", "npm:3.484.0"],\ + ["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/domain-core", "workspace:packages/domain-core"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ diff --git a/.yarn/cache/@cbor-extract-cbor-extract-darwin-arm64-npm-2.1.1-7f6025512f-10.zip b/.yarn/cache/@cbor-extract-cbor-extract-darwin-arm64-npm-2.1.1-7f6025512f-10.zip deleted file mode 100644 index ed30bfc94888de208e76f8e95c9e324c2b16d135..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8406 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 N85|5uKH1N`{{tdTJSYGF diff --git a/.yarn/cache/fsevents-patch-19706e7e35-10.zip b/.yarn/cache/fsevents-patch-19706e7e35-10.zip deleted file mode 100644 index aff1ab12ce57f312cc3bc58c78597020f7980e62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23750 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 diff --git a/packages/analytics/src/Domain/Email/daily-analytics-report.html.ts b/packages/analytics/src/Domain/Email/daily-analytics-report.html.ts index 1f63dd30a..3cedc9675 100644 --- a/packages/analytics/src/Domain/Email/daily-analytics-report.html.ts +++ b/packages/analytics/src/Domain/Email/daily-analytics-report.html.ts @@ -4,6 +4,7 @@ import { TimerInterface } from '@standardnotes/time' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { StatisticMeasureName } from '../Statistics/StatisticMeasureName' import { Period } from '../Time/Period' +import { safeHtml } from '@standardnotes/common' const countActiveUsers = (measureName: string, data: any): { yesterday: number; last30Days: number } => { const totalActiveUsersLast30DaysIncludingToday = data.statisticsOverTime.find( @@ -567,7 +568,7 @@ export const html = (data: any, timer: TimerInterface) => { const totalActivePlusUsers = countActiveUsers(StatisticMeasureName.NAMES.ActivePlusUsers, data) const totalActiveProUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveProUsers, data) - return `
+ return safeHtml`

Hello,

Here are some statistics from yesterday: diff --git a/packages/auth/src/Domain/Email/offline-subscription-token-created.html.ts b/packages/auth/src/Domain/Email/offline-subscription-token-created.html.ts index 6e7497ba4..99a250461 100644 --- a/packages/auth/src/Domain/Email/offline-subscription-token-created.html.ts +++ b/packages/auth/src/Domain/Email/offline-subscription-token-created.html.ts @@ -1,4 +1,6 @@ -export const html = (userEmail: string, offlineSubscriptionDashboardUrl: string) => `

+import { safeHtml } from '@standardnotes/common' + +export const html = (userEmail: string, offlineSubscriptionDashboardUrl: string) => safeHtml`
diff --git a/packages/auth/src/Domain/Email/shared-subscription-invitation-created.html.ts b/packages/auth/src/Domain/Email/shared-subscription-invitation-created.html.ts index 2ed1bacb8..422a0a5e8 100644 --- a/packages/auth/src/Domain/Email/shared-subscription-invitation-created.html.ts +++ b/packages/auth/src/Domain/Email/shared-subscription-invitation-created.html.ts @@ -1,4 +1,6 @@ -export const html = (inviterIdentifier: string, inviteUuid: string) => `

Hello,

+import { safeHtml } from '@standardnotes/common' + +export const html = (inviterIdentifier: string, inviteUuid: string) => safeHtml`

Hello,

You've been invited to join a Standard Notes premium subscription at no cost. ${inviterIdentifier} has invited you to share the benefits of their subscription plan.

Accept Invite diff --git a/packages/auth/src/Domain/Email/user-email-changed.html.ts b/packages/auth/src/Domain/Email/user-email-changed.html.ts index c8f7d2d35..c275bc780 100644 --- a/packages/auth/src/Domain/Email/user-email-changed.html.ts +++ b/packages/auth/src/Domain/Email/user-email-changed.html.ts @@ -1,4 +1,6 @@ -export const html = (newEmail: string) => ` +import { safeHtml } from '@standardnotes/common' + +export const html = (newEmail: string) => safeHtml`

Hello,

We are writing to inform you that your request to update your email address has been successfully processed. The email address associated with your Standard Notes account has now been changed to the following:

diff --git a/packages/auth/src/Domain/Email/user-invited-to-shared-vault.html.ts b/packages/auth/src/Domain/Email/user-invited-to-shared-vault.html.ts index bcd1be005..8bca278bc 100644 --- a/packages/auth/src/Domain/Email/user-invited-to-shared-vault.html.ts +++ b/packages/auth/src/Domain/Email/user-invited-to-shared-vault.html.ts @@ -1,4 +1,6 @@ -export const html = () => ` +import { safeHtml } from '@standardnotes/common' + +export const html = () => safeHtml`

Hello,

You've been invited to join a shared vault. This shared workspace will help you collaborate and securely manage notes and files.

diff --git a/packages/auth/src/Domain/Email/user-signed-in.html.ts b/packages/auth/src/Domain/Email/user-signed-in.html.ts index c72b9210e..a2be181d7 100644 --- a/packages/auth/src/Domain/Email/user-signed-in.html.ts +++ b/packages/auth/src/Domain/Email/user-signed-in.html.ts @@ -1,4 +1,6 @@ -export const html = (email: string, device: string, browser: string, timeAndDate: string) => ` +import { safeHtml } from '@standardnotes/common' + +export const html = (email: string, device: string, browser: string, timeAndDate: string) => safeHtml`

Hello,

We've detected a new sign-in to your account ${email}

diff --git a/packages/common/src/Domain/Html/SafeHtml.spec.ts b/packages/common/src/Domain/Html/SafeHtml.spec.ts new file mode 100644 index 000000000..5d65a56aa --- /dev/null +++ b/packages/common/src/Domain/Html/SafeHtml.spec.ts @@ -0,0 +1,16 @@ +import { safeHtml } from './SafeHtml' + +describe('html', () => { + test('Should escape html from user input', () => { + const basicStringInput = '

User

' + const numberValue = 10 + expect(safeHtml`

Hello world, ${basicStringInput} ${numberValue}

`).toBe( + '

Hello world, <h1>User</h1> 10

', + ) + }) + + test('Should join arrays and escape', () => { + const arrayOfStrings = ['

User

', '

Test

'] + expect(safeHtml`

${arrayOfStrings}

`).toBe('

<h1>User</h1><p>Test</p>

') + }) +}) diff --git a/packages/common/src/Domain/Html/SafeHtml.ts b/packages/common/src/Domain/Html/SafeHtml.ts new file mode 100644 index 000000000..e49bd13c8 --- /dev/null +++ b/packages/common/src/Domain/Html/SafeHtml.ts @@ -0,0 +1,32 @@ +function escapeHTML(str: string) { + return str + .replace(/&/g, '&') + .replace(/>/g, '>') + .replace(/) { + const raw = literals.raw + + let result = raw[0] + + for (let index = 1; index < raw.length; index++) { + const literal = raw[index] + let substitution = substitutions[index - 1] + if (Array.isArray(substitution)) { + substitution = substitution.join('') + } else if (typeof substitution === 'number') { + substitution = substitution.toString() + } + substitution = escapeHTML(substitution) + result += substitution + literal + } + + return result +} diff --git a/packages/common/src/Domain/index.ts b/packages/common/src/Domain/index.ts index d788e6484..c6fe229d0 100644 --- a/packages/common/src/Domain/index.ts +++ b/packages/common/src/Domain/index.ts @@ -18,3 +18,4 @@ export * from './Subscription/SubscriptionName' export * from './Type/Either' export * from './Type/Only' export * from './User/UserRequestType' +export * from './Html/SafeHtml' diff --git a/packages/scheduler/package.json b/packages/scheduler/package.json index 462173b31..3de9e7e50 100644 --- a/packages/scheduler/package.json +++ b/packages/scheduler/package.json @@ -29,6 +29,7 @@ "dependencies": { "@aws-sdk/client-sns": "^3.484.0", "@aws-sdk/client-sqs": "^3.484.0", + "@standardnotes/common": "workspace:^", "@standardnotes/domain-core": "workspace:^", "@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*", diff --git a/packages/scheduler/src/Domain/Email/encourage-email-backups.html.ts b/packages/scheduler/src/Domain/Email/encourage-email-backups.html.ts index 9285790aa..f33e77b94 100644 --- a/packages/scheduler/src/Domain/Email/encourage-email-backups.html.ts +++ b/packages/scheduler/src/Domain/Email/encourage-email-backups.html.ts @@ -1,4 +1,6 @@ -export const html = `
+import { safeHtml } from '@standardnotes/common' + +export const html = safeHtml`

Did you know you can enable daily email backups for your account? This free feature sends an email to your inbox with an encrypted backup file including all your notes and tags. diff --git a/packages/scheduler/src/Domain/Email/encourage-subscription-purchasing.html.ts b/packages/scheduler/src/Domain/Email/encourage-subscription-purchasing.html.ts index 07473f08b..ed148ac82 100644 --- a/packages/scheduler/src/Domain/Email/encourage-subscription-purchasing.html.ts +++ b/packages/scheduler/src/Domain/Email/encourage-subscription-purchasing.html.ts @@ -1,4 +1,6 @@ -export const html = (registrationDate: string, annualPlusPrice: number, annualProPrice: number) => `

+import { safeHtml } from '@standardnotes/common' + +export const html = (registrationDate: string, annualPlusPrice: number, annualProPrice: number) => safeHtml`

Hi there,

We hope you've been finding great use out of Standard Notes. We built Standard Notes to be a secure place for diff --git a/packages/scheduler/src/Domain/Email/exit-interview.html.ts b/packages/scheduler/src/Domain/Email/exit-interview.html.ts index e5420a50b..231a611f3 100644 --- a/packages/scheduler/src/Domain/Email/exit-interview.html.ts +++ b/packages/scheduler/src/Domain/Email/exit-interview.html.ts @@ -1,4 +1,6 @@ -export const html = `

+import { safeHtml } from '@standardnotes/common' + +export const html = safeHtml`

We're truly sad to see you leave. Our mission is simple: build the best, most private, and most secure note-taking app available. It's clear we've fallen short of your expectations somewhere along the way. diff --git a/packages/syncing-server/src/Domain/Email/dropbox-backup-failed.html.ts b/packages/syncing-server/src/Domain/Email/dropbox-backup-failed.html.ts index da8a061f5..98cff02da 100644 --- a/packages/syncing-server/src/Domain/Email/dropbox-backup-failed.html.ts +++ b/packages/syncing-server/src/Domain/Email/dropbox-backup-failed.html.ts @@ -1,4 +1,6 @@ -export const html = `

Hello,

+import { safeHtml } from '@standardnotes/common' + +export const html = safeHtml`

Hello,

We recently tried backing up your data to Dropbox, but an issue prevented us from doing so.

The usual cause is an expired or revoked token from your sync provider. Please follow diff --git a/packages/syncing-server/src/Domain/Email/email-backup-attachment-created.html.ts b/packages/syncing-server/src/Domain/Email/email-backup-attachment-created.html.ts index 8f3215bd8..606ae77ba 100644 --- a/packages/syncing-server/src/Domain/Email/email-backup-attachment-created.html.ts +++ b/packages/syncing-server/src/Domain/Email/email-backup-attachment-created.html.ts @@ -1,4 +1,6 @@ -export const html = (email: string) => ` +import { safeHtml } from '@standardnotes/common' + +export const html = (email: string) => safeHtml`

Your encrypted data backup is attached for ${email}. You can import this file using the Standard Notes web or desktop app, or by using the offline decryption script available at diff --git a/packages/syncing-server/src/Domain/Email/google-drive-backup-failed.html.ts b/packages/syncing-server/src/Domain/Email/google-drive-backup-failed.html.ts index 4654d40e9..2771f883b 100644 --- a/packages/syncing-server/src/Domain/Email/google-drive-backup-failed.html.ts +++ b/packages/syncing-server/src/Domain/Email/google-drive-backup-failed.html.ts @@ -1,4 +1,6 @@ -export const html = `

Hello,

+import { safeHtml } from '@standardnotes/common' + +export const html = safeHtml`

Hello,

We recently tried backing up your data to Google Drive Sync, but an issue prevented us from doing so.

diff --git a/packages/syncing-server/src/Domain/Email/one-drive-backup-failed.html.ts b/packages/syncing-server/src/Domain/Email/one-drive-backup-failed.html.ts index 90fe94975..0172111de 100644 --- a/packages/syncing-server/src/Domain/Email/one-drive-backup-failed.html.ts +++ b/packages/syncing-server/src/Domain/Email/one-drive-backup-failed.html.ts @@ -1,4 +1,6 @@ -export const html = `

Hello,

+import { safeHtml } from '@standardnotes/common' + +export const html = safeHtml`

Hello,

We recently tried backing up your data to OneDrive Sync, but an issue prevented us from doing so.

diff --git a/yarn.lock b/yarn.lock index 69d4fd6f5..9505ade9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6164,6 +6164,7 @@ __metadata: dependencies: "@aws-sdk/client-sns": "npm:^3.484.0" "@aws-sdk/client-sqs": "npm:^3.484.0" + "@standardnotes/common": "workspace:^" "@standardnotes/domain-core": "workspace:^" "@standardnotes/domain-events": "workspace:*" "@standardnotes/domain-events-infra": "workspace:*"