Files
Jeremy Daer d3f22d78e1 Harden message content filtering + bump thruster to 0.1.23 (#237)
* Bump thruster 0.1.15 → 0.1.23

* Scrub disallowed attributes on allowed tags in message rendering

SanitizeTags removes disallowed tags from message presentation, but
attributes on the tags it allows passed through untouched. Extend the
content-filter chain with a SanitizeAttributes filter that runs Rails'
safe-list sanitizer over the remaining markup, stripping event-handler
attributes and unsafe URI schemes as defense-in-depth alongside the
existing Content-Security-Policy.

Running it after SanitizeTags with the same allowed-tags list makes the
sanitizer's tag pass a no-op, preserving SanitizeTags' remove-not-unwrap
semantics while scrubbing attributes. The attribute allowlist is the
standard ActionText set (which keeps attachments intact) plus class,
which presentation styling relies on.
2026-08-10 15:55:02 -07:00

35 lines
1.8 KiB
Plaintext

<%# Be sure to check/update messages/_template.html.erb when changing this file %>
<%# Bump this version when the message presentation filters change what they emit. Editing this line changes the template digest, which busts BOTH this fragment cache and the collection cache that keys on this partial's digest (helper Ruby changes alone don't). %>
<% cache [ message, "presentation-v2" ] do %>
<%= message_tag message do %>
<h2 class="message__day-separator"><%= local_datetime_tag message.created_at, style: :date %></h2>
<figure class="avatar message__avatar">
<%= avatar_tag message.creator %>
</figure>
<turbo-frame id="<%= dom_id(message, :edit) %>">
<div class="message__body">
<div class="message__body-content">
<div class="message__meta">
<h3 class="message__heading">
<span class="message__author" title="<%= message.creator.title %>">
<strong data-reply-target="author"><%= message.creator.name %></strong>
</span>
<%= link_to message_timestamp(message, class: "message__timestamp"), room_at_message_path(message.room, message), target: "_top",
class: "message__permalink" %>
<span class="message__room">
<%= link_to room_display_name(message.room, for_user: nil), room_at_message_path(message.room, message), target: "_top", data: { reply_target: "link" } %>
</span>
</h3>
<%= render "messages/actions", message: message, url: room_at_message_url(message.room, message) %>
</div>
<%= render "messages/presentation", message: message %>
<%= render "messages/boosts/boosts", message: message %>
</div>
</div>
</turbo-frame>
<% end %>
<% end %>