Skip to content

Conversation

@mroderick
Copy link
Collaborator

@mroderick mroderick commented Jan 20, 2026

This PR is a solution for #2436.

Summary

Fixes a security vulnerability where event descriptions using .html_safe could allow XSS attacks in invitation emails.

Changes

  • Replaced @event.description.html_safe with sanitize(@event.description) in:
    • app/views/event_invitation_mailer/invite_student.html.haml:19
    • app/views/event_invitation_mailer/invite_coach.html.haml:19
  • Added XSS protection test specs in spec/mailers/event_invitation_mailer_spec.rb

Security Impact

The sanitize() helper:

  • Strips dangerous tags like <script> and event handlers (onclick, etc.)
  • Allows safe HTML formatting tags (<p>, <strong>, <em>, <a>, <br>, etc.)
  • Uses Rails' built-in SafeListSanitizer with secure defaults
  • Matches the pattern already used in non-email views throughout the codebase

Test Plan

  • Updated email templates to use sanitize
  • Added XSS protection tests
  • CI pipeline runs all tests (draft PR for CI validation)

Notes

This PR is marked as draft to validate tests pass in CI. Local test setup not available.

Related files NOT changed (for future consideration):

  • Meeting invitation mailer also uses .html_safe on descriptions
  • Virtual workshop invitation mailer uses .html_safe for i18n strings with links
  • Workshop invitation mailer outputs descriptions without sanitization

Replace `.html_safe` with `sanitize()` for event descriptions in email
templates to prevent potential XSS attacks while still allowing safe HTML
formatting tags.

Changes:
- Replace @event.description.html_safe with sanitize(@event.description)
  in invite_student.html.haml
- Replace @event.description.html_safe with sanitize(@event.description)
  in invite_coach.html.haml
- Add XSS protection test specs to verify dangerous tags are stripped
  while safe content is preserved

The sanitize helper uses Rails' built-in SafeListSanitizer which:
- Strips dangerous tags like <script> and event handlers (onclick, etc.)
- Allows safe HTML formatting tags (p, strong, em, a, br, etc.)
- Matches the pattern already used in non-email views throughout the codebase

Security: Fixes potential XSS vulnerability where malicious HTML/JavaScript
in event descriptions could be executed in invitation emails.
@mroderick mroderick marked this pull request as ready for review January 20, 2026 18:29
EventInvitationMailer.invite_student(event_with_html, member, invitation_with_html).deliver_now

expect(email.body.encoded).not_to include('<script>')
expect(email.body.encoded).to include('Safe content')
Copy link
Contributor

Choose a reason for hiding this comment

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

Could be worth setting the expected text to <p>Safe content<p> to communicate that some HTML is allowed?

@mikej
Copy link
Contributor

mikej commented Jan 20, 2026

Looks good. Just one suggestion about a possible improvement to the tests.

Happy for this to be merged as-is if you prefer though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants