Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/12944.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `Cross-Origin-Resource-Policy: cross-origin` header to content repository's thumbnail and download endpoints.
11 changes: 11 additions & 0 deletions synapse/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
"""
Wraps `respond_with_html_bytes` by first encoding HTML from a str to UTF-8 bytes.
Expand Down
7 changes: 6 additions & 1 deletion synapse/rest/media/v1/download_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
import logging
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.site import SynapseRequest

Expand All @@ -38,6 +42,7 @@ def __init__(self, hs: "HomeServer", media_repo: "MediaRepository"):

async def _async_render_GET(self, request: SynapseRequest) -> None:
set_cors_headers(request)
set_corp_headers(request)
request.setHeader(
b"Content-Security-Policy",
b"sandbox;"
Expand Down
7 changes: 6 additions & 1 deletion synapse/rest/media/v1/thumbnail_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple

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.site import SynapseRequest
from synapse.rest.media.v1.media_storage import MediaStorage
Expand Down Expand Up @@ -58,6 +62,7 @@ def __init__(

async def _async_render_GET(self, request: SynapseRequest) -> None:
set_cors_headers(request)
set_corp_headers(request)
server_name, media_id, _ = parse_media_id(request)
width = parse_integer(request, "width", required=True)
height = parse_integer(request, "height", required=True)
Expand Down
20 changes: 20 additions & 0 deletions tests/rest/media/v1/test_media_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,12 @@ def _test_thumbnail(

if expected_found:
self.assertEqual(channel.code, 200)

self.assertEqual(
channel.headers.getRawHeaders(b"Cross-Origin-Resource-Policy"),
[b"cross-origin"],
)

if expected_body is not None:
self.assertEqual(
channel.result["body"], expected_body, channel.result["body"]
Expand Down Expand Up @@ -549,6 +555,20 @@ def test_x_robots_tag_header(self) -> None:
[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:
"""A spam checker module that rejects all media that includes the bytes
Expand Down