mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-09-14 20:42:04 +09:00
Render link previews only from web URLs
A link preview's link and image come from attributes on the message body, which the composer fills in from the unfurl the server performed. A body written by hand can put anything in those attributes, and the preview partial rendered them as they were. Keep the link and the image only when they parse as absolute http or https URLs, so nothing in a message body can aim either one at another scheme or at a path on this Campfire, and render the title and the description as text. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186eyzivcTn6wqjEE4Wnxdt
This commit is contained in:
@@ -20,6 +20,35 @@ class RoomsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert response.cookies[:last_room] = users(:david).rooms.last.id
|
||||
end
|
||||
|
||||
test "show renders a link preview written by hand without its off-scheme image and link" do
|
||||
room = rooms(:watercooler)
|
||||
post room_messages_url(room, format: :turbo_stream), params: { message: {
|
||||
body: link_preview_body(href: "javascript:alert(1)", url: "data:image/svg+xml;base64,PHN2Zy8+"),
|
||||
client_message_id: "hand-written-preview" } }
|
||||
assert_response :success
|
||||
|
||||
get room_url(room)
|
||||
|
||||
assert_response :success
|
||||
assert_no_match /javascript:alert/, response.body
|
||||
assert_no_match /data:image\/svg/, response.body
|
||||
assert_match "Free cookies", response.body
|
||||
end
|
||||
|
||||
test "show renders an unfurled link preview" do
|
||||
room = rooms(:watercooler)
|
||||
post room_messages_url(room, format: :turbo_stream), params: { message: {
|
||||
body: link_preview_body(href: "https://example.com/page", url: "https://example.com/image.png"),
|
||||
client_message_id: "unfurled-preview" } }
|
||||
assert_response :success
|
||||
|
||||
get room_url(room)
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{<img src="https://example\.com/image\.png"}, response.body
|
||||
assert_match %r{href="https://example\.com/page"}, response.body
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_turbo_stream_broadcasts :rooms, count: 1 do
|
||||
assert_difference -> { Room.count }, -1 do
|
||||
@@ -42,4 +71,10 @@ class RoomsControllerTest < ActionDispatch::IntegrationTest
|
||||
delete room_url(rooms(:designers))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def link_preview_body(href:, url:)
|
||||
%(<div><action-text-attachment content-type="application/vnd.actiontext.opengraph-embed" ) +
|
||||
%(href="#{href}" url="#{url}" filename="Free cookies" caption="Cookies here"></action-text-attachment></div>)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user