fix(email): HTML-escape interpolated values in email templates#48
Open
clawedassistant26 wants to merge 1 commit into
Open
fix(email): HTML-escape interpolated values in email templates#48clawedassistant26 wants to merge 1 commit into
clawedassistant26 wants to merge 1 commit into
Conversation
Titles, actors and tenant brand names were interpolated straight into the HTML email bodies. A GitHub issue/PR title is attacker-controlled, so sendGithubClosedNotification rendered untrusted markup (e.g. <script>/<img onerror>) into the owner's notification email; the same applied to the tenant brand in the waitlist and password-reset emails. Add an escapeHtml helper and apply it to every dynamic value that lands in an HTML body. Plain-text bodies and subjects are left untouched. Adds tests/email-escape.test.mjs (fails before, passes after).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Dynamic values were interpolated straight into the HTML email bodies in
lib/email.tswith no escaping.sendGithubClosedNotificationrenderstitle,repoandactorinto HTML. A GitHub issue/PR title is attacker-controlled — anyone can open an issue titled<script>...or<img src=x onerror=...>, which then lands unescaped in the repo owner's notification email.sendWaitlistVerificationandsendPasswordResetinterpolate the tenantbrandinto HTML the same way.Reproduce (before)
Stub
fetch, callsendGithubClosedNotification({ title: '<script>alert(1)</script>', actor: 'evil"><b>x</b>', ... }), and the outgoing Resendhtmlbody contains the raw<script>/<b>markup.Fix
Add a small
escapeHtmlhelper and apply it to every dynamic value that lands in an HTML body (brand,title,repo,actor, and the link URL). Plain-text bodies and subjects are intentionally left untouched — they aretext/plain, not HTML. Benign brand names render exactly as before.Test
Adds
tests/email-escape.test.mjswhich captures the outgoing payload and asserts the HTML body is escaped. It fails on the current code (3/4) and passes after the fix (4/4). Full existing suite stays green (the one unrelated failure,affiliate-commission, is a missing@libsql/clientdev-dep in my sandbox, not touched here).