Add Cross-Origin-Resource-Policy header to thumbnail and download media endpoints (#12944)

This commit is contained in:
Robert Long 2022-06-27 06:44:05 -07:00 committed by GitHub
parent 3c5549e74a
commit 9b683ea80f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 2 deletions

1
changelog.d/12944.misc Normal file
View File

@ -0,0 +1 @@
Add `Cross-Origin-Resource-Policy: cross-origin` header to content repository's thumbnail and download endpoints.

View File

@ -928,6 +928,17 @@ def set_cors_headers(request: Request) -> None:
) )
def set_corp_headers(request: Request) -> None:
"""Set the CORP headers so that javascript running in a web browsers can
embed the resource returned from this request when their client requires
the `Cross-Origin-Embedder-Policy: require-corp` header.
Args:
request: The http request to add the CORP header to.
"""
request.setHeader(b"Cross-Origin-Resource-Policy", b"cross-origin")
def respond_with_html(request: Request, code: int, html: str) -> None: def respond_with_html(request: Request, code: int, html: str) -> None:
""" """
Wraps `respond_with_html_bytes` by first encoding HTML from a str to UTF-8 bytes. Wraps `respond_with_html_bytes` by first encoding HTML from a str to UTF-8 bytes.

View File

@ -15,7 +15,11 @@
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from synapse.http.server import DirectServeJsonResource, set_cors_headers from synapse.http.server import (
DirectServeJsonResource,
set_corp_headers,
set_cors_headers,
)
from synapse.http.servlet import parse_boolean from synapse.http.servlet import parse_boolean
from synapse.http.site import SynapseRequest from synapse.http.site import SynapseRequest
@ -38,6 +42,7 @@ class DownloadResource(DirectServeJsonResource):
async def _async_render_GET(self, request: SynapseRequest) -> None: async def _async_render_GET(self, request: SynapseRequest) -> None:
set_cors_headers(request) set_cors_headers(request)
set_corp_headers(request)
request.setHeader( request.setHeader(
b"Content-Security-Policy", b"Content-Security-Policy",
b"sandbox;" b"sandbox;"

View File

@ -18,7 +18,11 @@ import logging
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
from synapse.api.errors import SynapseError from synapse.api.errors import SynapseError
from synapse.http.server import DirectServeJsonResource, set_cors_headers from synapse.http.server import (
DirectServeJsonResource,
set_corp_headers,
set_cors_headers,
)
from synapse.http.servlet import parse_integer, parse_string from synapse.http.servlet import parse_integer, parse_string
from synapse.http.site import SynapseRequest from synapse.http.site import SynapseRequest
from synapse.rest.media.v1.media_storage import MediaStorage from synapse.rest.media.v1.media_storage import MediaStorage
@ -58,6 +62,7 @@ class ThumbnailResource(DirectServeJsonResource):
async def _async_render_GET(self, request: SynapseRequest) -> None: async def _async_render_GET(self, request: SynapseRequest) -> None:
set_cors_headers(request) set_cors_headers(request)
set_corp_headers(request)
server_name, media_id, _ = parse_media_id(request) server_name, media_id, _ = parse_media_id(request)
width = parse_integer(request, "width", required=True) width = parse_integer(request, "width", required=True)
height = parse_integer(request, "height", required=True) height = parse_integer(request, "height", required=True)

View File

@ -481,6 +481,12 @@ class MediaRepoTests(unittest.HomeserverTestCase):
if expected_found: if expected_found:
self.assertEqual(channel.code, 200) self.assertEqual(channel.code, 200)
self.assertEqual(
channel.headers.getRawHeaders(b"Cross-Origin-Resource-Policy"),
[b"cross-origin"],
)
if expected_body is not None: if expected_body is not None:
self.assertEqual( self.assertEqual(
channel.result["body"], expected_body, channel.result["body"] channel.result["body"], expected_body, channel.result["body"]
@ -549,6 +555,20 @@ class MediaRepoTests(unittest.HomeserverTestCase):
[b"noindex, nofollow, noarchive, noimageindex"], [b"noindex, nofollow, noarchive, noimageindex"],
) )
def test_cross_origin_resource_policy_header(self) -> None:
"""
Test that the Cross-Origin-Resource-Policy header is set to "cross-origin"
allowing web clients to embed media from the downloads API.
"""
channel = self._req(b"inline; filename=out" + self.test_image.extension)
headers = channel.headers
self.assertEqual(
headers.getRawHeaders(b"Cross-Origin-Resource-Policy"),
[b"cross-origin"],
)
class TestSpamChecker: class TestSpamChecker:
"""A spam checker module that rejects all media that includes the bytes """A spam checker module that rejects all media that includes the bytes