Add Cross-Origin-Resource-Policy header to thumbnail and download media endpoints (#12944)
This commit is contained in:
parent
3c5549e74a
commit
9b683ea80f
|
@ -0,0 +1 @@
|
||||||
|
Add `Cross-Origin-Resource-Policy: cross-origin` header to content repository's thumbnail and download endpoints.
|
|
@ -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.
|
||||||
|
|
|
@ -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;"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue