Cover markup-only OpenGraph title and description in link previews

Link previews fetch a page's OpenGraph title and description, and
Opengraph::Metadata strips tags from both before the values reach the
browser. When a field consists entirely of a markup tag, stripping
leaves it blank, the metadata fails its presence validation, and the
unfurl endpoint returns no content, so no preview is produced.

Add regression tests at the model and controller layers that pin this:
a title or description made only of a markup tag is stripped to blank
and rejected, and the endpoint answers 204. The existing sanitize tests
only cover fields that keep non-blank text after stripping, so this
blank-and-rejected path was previously untested.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186eyzivcTn6wqjEE4Wnxdt
This commit is contained in:
Rosa Gutierrez
2026-09-11 18:33:06 +02:00
committed by Rosa Gutierrez
parent 8722057545
commit 5742dfaf73
2 changed files with 38 additions and 0 deletions
@@ -37,6 +37,21 @@ class UnfurlLinksControllerTest < ActionDispatch::IntegrationTest
assert_response :no_content
end
test "create returns no content when the title and description are only a markup tag" do
image_tag = "<img src='x' onerror='alert(document.domain)'/>"
body = "<html><head>" \
"<meta property=\"og:url\" content=\"https://example.com\">" \
"<meta property=\"og:title\" content=\"#{image_tag}\">" \
"<meta property=\"og:description\" content=\"#{image_tag}\">" \
"<meta property=\"og:image\" content=\"https://example.com/image.png\">" \
"</head></html>"
WebMock.stub_request(:get, "https://www.example.com/").to_return(status: 200, body: body, headers: { content_type: "text/html" })
WebMock.stub_request(:head, "https://example.com/image.png").to_return(status: 200, headers: { content_type: "image/png" })
post unfurl_link_url, params: { url: "https://www.example.com" }
assert_response :no_content
end
test "create with a missing URL" do
assert_raise ActionController::ParameterMissing do
post unfurl_link_url, params: { url: "" }
+23
View File
@@ -147,6 +147,29 @@ class Opengraph::MetadataTest < ActiveSupport::TestCase
assert_equal "Hello", metadata.description
end
test "a title or description that is entirely a markup tag is stripped to blank and rejected" do
body = <<~HTML
<html>
<head>
<meta property="og:title" content="<img src='x' onerror='alert(document.domain)'/>">
<meta property="og:description" content="<img src='x' onerror='alert(document.domain)'/>">
<meta property="og:image" content="https://example.com/image.png">
</head>
</html>
HTML
WebMock.stub_request(:get, "https://www.example.com/").to_return(status: 200, body: body, headers: { content_type: "text/html" })
WebMock.stub_request(:head, "https://example.com/image.png").to_return(status: 200, headers: { content_type: "image/png" })
metadata = Opengraph::Metadata.from_url("https://www.example.com")
assert_not metadata.valid?
assert_equal "", metadata.title
assert_equal "", metadata.description
assert_includes metadata.errors.full_messages, "Title can't be blank"
assert_includes metadata.errors.full_messages, "Description can't be blank"
end
test "does not allow SVG content type for preview image" do
body = <<~HTML
<html>