markdown: Run URL preview links through camo.

Not proxying these requests through camo is a security concern.
Furthermore, on the desktop client, any embed image which is hosted on
a server with an expired or otherwise invalid certificate will trigger
a blocking modal window with no clear source and a confusing error
message; see zulip/zulip-desktop#1119.

Rewrite all `message_embed_image` URLs through camo, if it is enabled.
This commit is contained in:
Alex Vandiver 2021-10-20 17:48:28 -07:00 committed by Tim Abbott
parent 0ddf319709
commit 52f74bbd9b
2 changed files with 15 additions and 0 deletions

View File

@ -712,6 +712,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
container = SubElement(root, "div") container = SubElement(root, "div")
container.set("class", "message_embed") container.set("class", "message_embed")
img_link = get_camo_url(img_link)
img = SubElement(container, "a") img = SubElement(container, "a")
img.set("style", "background-image: url(" + img_link + ")") img.set("style", "background-image: url(" + img_link + ")")
img.set("href", link) img.set("href", link)

View File

@ -522,6 +522,7 @@ class PreviewTestCase(ZulipTestCase):
msg = self._send_message_with_test_org_url(sender=self.example_user("prospero")) msg = self._send_message_with_test_org_url(sender=self.example_user("prospero"))
self.assertIn(embedded_link, msg.rendered_content) self.assertIn(embedded_link, msg.rendered_content)
@override_settings(CAMO_URI="")
def test_inline_url_embed_preview(self) -> None: def test_inline_url_embed_preview(self) -> None:
with_preview = '<p><a href="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url(http://ia.media-imdb.com/images/rock.jpg)"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>' with_preview = '<p><a href="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url(http://ia.media-imdb.com/images/rock.jpg)"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>'
without_preview = '<p><a href="http://test.org/">http://test.org/</a></p>' without_preview = '<p><a href="http://test.org/">http://test.org/</a></p>'
@ -537,6 +538,17 @@ class PreviewTestCase(ZulipTestCase):
) )
self.assertEqual(msg.rendered_content, without_preview) self.assertEqual(msg.rendered_content, without_preview)
def test_inline_url_embed_preview_with_camo(self) -> None:
camo_url = get_camo_url("http://ia.media-imdb.com/images/rock.jpg")
with_preview = (
'<p><a href="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url('
+ camo_url
+ ')"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>'
)
msg = self._send_message_with_test_org_url(sender=self.example_user("hamlet"))
self.assertEqual(msg.rendered_content, with_preview)
@override_settings(CAMO_URI="")
@override_settings(INLINE_URL_EMBED_PREVIEW=True) @override_settings(INLINE_URL_EMBED_PREVIEW=True)
def test_inline_relative_url_embed_preview(self) -> None: def test_inline_relative_url_embed_preview(self) -> None:
# Relative URLs should not be sent for URL preview. # Relative URLs should not be sent for URL preview.
@ -548,6 +560,7 @@ class PreviewTestCase(ZulipTestCase):
) )
patched.assert_not_called() patched.assert_not_called()
@override_settings(CAMO_URI="")
def test_inline_url_embed_preview_with_relative_image_url(self) -> None: def test_inline_url_embed_preview_with_relative_image_url(self) -> None:
with_preview_relative = '<p><a href="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url(http://test.org/images/rock.jpg)"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>' with_preview_relative = '<p><a href="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url(http://test.org/images/rock.jpg)"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>'
# Try case where the Open Graph image is a relative URL. # Try case where the Open Graph image is a relative URL.
@ -708,6 +721,7 @@ class PreviewTestCase(ZulipTestCase):
) )
@responses.activate @responses.activate
@override_settings(CAMO_URI="")
@override_settings(INLINE_URL_EMBED_PREVIEW=True) @override_settings(INLINE_URL_EMBED_PREVIEW=True)
def test_link_preview_no_content_type_header(self) -> None: def test_link_preview_no_content_type_header(self) -> None:
user = self.example_user("hamlet") user = self.example_user("hamlet")