Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email: Mark HTML comments as "safe" in email templates #64546

Merged
merged 3 commits into from Mar 28, 2023

Conversation

gillesdemey
Copy link
Member

@gillesdemey gillesdemey commented Mar 9, 2023

What is this feature?

This change adds an additional "safeHTML" function to the email templates to allow comment blocks to be preserved after compiling the template with Go's html/template package.

Why do we need this feature?

MJML outputs comments that are specific for MS Outlook and if those are not preserved the email is rendered incorrectly.

Which issue(s) does this PR fix?:

Fixes #63996

Special notes for your reviewer:

There's a security implication here in case the author of the email templates is untrusted.

I still have to figure out how to port this to grafana-enterprise

I've tested this with an Outlook for Desktop client I had access to from a friend of a friend and they said it looked correct 馃槅

This changes add an additional "safeHTML" function to the email templates to allow comment blocks to be preserved after compiling the template with Go's html/template package.

MJML outputs comments that are specific for MS Outlook and if those are not preserved the email is rendered incorrectly.
@gillesdemey gillesdemey added type/bug pr/needs-manual-testing Before merge some help with manual testing & verification is requested area/backend area/mailing os/windows backport v9.4.x Mark PR for automatic backport to v9.4.x labels Mar 9, 2023
@gillesdemey gillesdemey requested a review from a team as a code owner March 9, 2023 17:20
@gillesdemey gillesdemey self-assigned this Mar 9, 2023
@gillesdemey gillesdemey requested review from a team as code owners March 9, 2023 17:20
@gillesdemey gillesdemey requested review from tskarhed, JoaoSilvaGrafana, ashharrison90, papagian, zserge and mildwonkey and removed request for a team March 9, 2023 17:20
@gillesdemey gillesdemey added this to the 9.4.5 milestone Mar 9, 2023
* to work with MS Outlook on the Desktop.
*/
const HTML_SAFE_FUNC = 'safeHTML';
const commentBlock = /(\<\!\-\-(?:.|\n|\r)*?-->)/g;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex might be a bit too naive as it will try to match <!-- foo --> but comments might still be rendered when there's some other character in the closing HTML comment. One possible character might be !, so <!-- foo --!> might still be a valid comment, but I'm uncertain if that's an issue in this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that outputs HTML in the compilation pipeline for now is MJML, so as long as it outputs semantically correct HTML comments (which I believe it does) this shoudn't be a concern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll still update it to a simpler regex, /(<!--[\s\S]*?-->)/g should work too and be less greedy (it doesn't match <!-- foo --!>)

@grafanabot grafanabot removed this from the 9.4.5 milestone Mar 13, 2023
@grafanabot
Copy link
Contributor

This pull request was removed from the 9.4.5 milestone because 9.4.5 is currently being released.

@gillesdemey gillesdemey added this to the 9.4.6 milestone Mar 14, 2023
@jmatosgrafana
Copy link
Contributor

@gillesdemey Following our security assessment with @KristianGrafana, it's OK to ignore the gosec warning for safeHTML: changing an email template requires write access to the filesystem of the Grafana server and Grafana admins are trusted (if you have access to html files of Grafana server you could just edit them to include malicious payloads).

Yet to avoid in the future dangerous usage of safeHTML where the input would be coming from an untrusted user and not a trusted admin, could we rename it to something that makes explicit the risks of calling this method ?

@gillesdemey
Copy link
Member Author

Changes made to this PR after meeting with @jmatosgrafana and @KristianGrafana

  • Renamed safeHTML to __dangerouslyInjectHTML to make anyone who uses this function think really hard about using it
  • Silenced with nolint:gosec since the attack vector requires write access to the emails directory and this requires admin privileges

@gillesdemey gillesdemey requested a review from a team March 14, 2023 13:13
@@ -1,5 +1,4 @@
default:
- 'clean'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now handled by make clean since we need to clean the folder before grunt is even invoked

npx mjml \
--config.beautify true \
--config.minify false \
--config.validationLevel=strict \
--config.keepComments=false \
./templates/*.mjml --output ../public/emails/
./templates/*.mjml --output ./dist/
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving the templates here first since we'll need to do some additional processing before we move them to ../public/emails

@grafanabot grafanabot removed this from the 9.4.6 milestone Mar 16, 2023
@grafanabot
Copy link
Contributor

This pull request was removed from the 9.4.6 milestone because 9.4.6 is currently being released.

@gillesdemey gillesdemey added this to the 9.4.8 milestone Mar 17, 2023
"HiddenSubject": hiddenSubjectTemplateFunc,
"Subject": subjectTemplateFunc,
"HiddenSubject": hiddenSubjectTemplateFunc,
"__dangerouslyInjectHTML": __dangerouslyInjectHTML,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I like this name. In Prometheus they use safeHtml for the same purpose. However, I think this name is more explicit about the purpose of the function (__ mean that it's internal, we already use this approach in alerting, and dangerously makes it clear that if you use it somewhere outside the intended workaround for HTML comments). So, I am leaning towards keeping it.

@yuri-tceretian
Copy link
Contributor

I tested the PR in windows. The change LGTM.

@gillesdemey gillesdemey merged commit ed82f96 into main Mar 28, 2023
7 checks passed
@gillesdemey gillesdemey deleted the fix/email-templates-mso branch March 28, 2023 11:05
@grafanabot

This comment was marked as resolved.

@grafanabot grafanabot added the backport-failed Failed to generate backport PR. Please resolve conflicts and create one manually. label Mar 28, 2023
gillesdemey added a commit that referenced this pull request Mar 28, 2023
@zerok zerok modified the milestones: 9.4.x, 9.4.8, 9.5.0 Apr 12, 2023
@zerok zerok mentioned this pull request Jun 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add to changelog area/backend area/frontend area/mailing area/security backport v9.4.x Mark PR for automatic backport to v9.4.x backport-failed Failed to generate backport PR. Please resolve conflicts and create one manually. os/windows pr/needs-manual-testing Before merge some help with manual testing & verification is requested type/bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Alerting: Email template appears broken in Outlook's desktop client
6 participants