Commit e7b7a29
authored
fix: escape task and language names in notification emails (#3842)
## Context
Triaging an external report claiming stored HTML injection in the signup
verification email. That specific claim does not hold — the verification
email contains no user-supplied name, and every template variable
already goes through `#strings.escapeXml` (covered by
`EmailServiceTest.it is not vulnerable to injection`).
Reviewing the surrounding code did turn up a genuine unescaped sink,
which this PR fixes.
## The issue
`TaskEmailComposer` builds the notification email body as raw HTML and
interpolates two user-supplied values without escaping:
- `task.name`
- `task.language.name`
That string is passed to `EmailParams.text`, which lands in the
`default` template's `content` variable — the one variable deliberately
injected as raw HTML
(`dangerouslyInjectValueAsHtmlWithoutSanitization`). So a project member
who names a task `<h1><a href="https://evil.example">…</a></h1>` gets
that markup rendered in the task notification email received by everyone
else on the project.
Severity is low: it requires project access, reaches only project
members, and email clients do not execute script. It is the same class
as the invitation-name bug fixed in #1898 — cosmetic markup injection
into a transactional email, useful only for making phishing content look
native.
## The fix
Escape both values with `HtmlUtils.htmlEscape` at the interpolation
site, matching what `InvitationEmailSender` already does.
`taskName()` stays plain text — it is also called from the billing repo,
which escapes at its own interpolation site (see tolgee/billing PR). The
two changes are independent; either can merge first.
## Tests
New `TaskEmailComposerTest` asserts both values come out escaped.
Verified it fails against the unpatched composer and passes with the
fix.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved task-assignment email security by safely escaping task and
language names in email links.
* Prevented special characters in names from being interpreted as HTML.
* **Tests**
* Added coverage to verify correct escaping in task notification emails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent 10d26c8 commit e7b7a29
2 files changed
Lines changed: 51 additions & 1 deletion
File tree
- backend/data/src
- main/kotlin/io/tolgee/service/notification
- test/kotlin/io/tolgee/unit
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
36 | | - | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
Lines changed: 49 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
0 commit comments