mirror of
https://git.youjo.love/youjo/youjo-be.git
synced 2024-11-20 05:49:54 +01:00
Sanitise Content-Type of media proxy URLs
This commit is contained in:
parent
f56267280e
commit
c101fa9a09
2 changed files with 57 additions and 2 deletions
|
@ -17,6 +17,8 @@ defmodule Pleroma.ReverseProxy do
|
||||||
@failed_request_ttl :timer.seconds(60)
|
@failed_request_ttl :timer.seconds(60)
|
||||||
@methods ~w(GET HEAD)
|
@methods ~w(GET HEAD)
|
||||||
|
|
||||||
|
@allowed_mime_types Pleroma.Config.get([Pleroma.Upload, :allowed_mime_types], [])
|
||||||
|
|
||||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||||
|
|
||||||
def max_read_duration_default, do: @max_read_duration
|
def max_read_duration_default, do: @max_read_duration
|
||||||
|
@ -250,6 +252,7 @@ defmodule Pleroma.ReverseProxy do
|
||||||
headers
|
headers
|
||||||
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|
||||||
|> build_resp_cache_headers(opts)
|
|> build_resp_cache_headers(opts)
|
||||||
|
|> sanitise_content_type()
|
||||||
|> build_resp_content_disposition_header(opts)
|
|> build_resp_content_disposition_header(opts)
|
||||||
|> build_csp_headers()
|
|> build_csp_headers()
|
||||||
|> Keyword.merge(Keyword.get(opts, :resp_headers, []))
|
|> Keyword.merge(Keyword.get(opts, :resp_headers, []))
|
||||||
|
@ -279,6 +282,21 @@ defmodule Pleroma.ReverseProxy do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp sanitise_content_type(headers) do
|
||||||
|
original_ct = get_content_type(headers)
|
||||||
|
|
||||||
|
safe_ct =
|
||||||
|
Pleroma.Web.Plugs.Utils.get_safe_mime_type(
|
||||||
|
%{allowed_mime_types: @allowed_mime_types},
|
||||||
|
original_ct
|
||||||
|
)
|
||||||
|
|
||||||
|
[
|
||||||
|
{"content-type", safe_ct}
|
||||||
|
| Enum.filter(headers, fn {k, _v} -> k != "content-type" end)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
defp build_resp_content_disposition_header(headers, opts) do
|
defp build_resp_content_disposition_header(headers, opts) do
|
||||||
opt = Keyword.get(opts, :inline_content_types, @inline_content_types)
|
opt = Keyword.get(opts, :inline_content_types, @inline_content_types)
|
||||||
|
|
||||||
|
|
|
@ -75,13 +75,16 @@ defmodule Pleroma.ReverseProxyTest do
|
||||||
Tesla.Mock.mock(fn %{method: :head, url: "/head"} ->
|
Tesla.Mock.mock(fn %{method: :head, url: "/head"} ->
|
||||||
%Tesla.Env{
|
%Tesla.Env{
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: [{"content-type", "text/html; charset=utf-8"}],
|
headers: [{"content-type", "image/png"}],
|
||||||
body: ""
|
body: ""
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
conn = ReverseProxy.call(Map.put(conn, :method, "HEAD"), "/head")
|
conn = ReverseProxy.call(Map.put(conn, :method, "HEAD"), "/head")
|
||||||
assert html_response(conn, 200) == ""
|
|
||||||
|
assert conn.status == 200
|
||||||
|
assert Conn.get_resp_header(conn, "content-type") == ["image/png"]
|
||||||
|
assert conn.resp_body == ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -252,4 +255,38 @@ defmodule Pleroma.ReverseProxyTest do
|
||||||
assert {"content-disposition", "attachment; filename=\"filename.jpg\""} in conn.resp_headers
|
assert {"content-disposition", "attachment; filename=\"filename.jpg\""} in conn.resp_headers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "content-type sanitisation" do
|
||||||
|
test "preserves video type", %{conn: conn} do
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "/content"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "video/mp4"}],
|
||||||
|
body: "test"
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
conn = ReverseProxy.call(Map.put(conn, :method, "GET"), "/content")
|
||||||
|
|
||||||
|
assert conn.status == 200
|
||||||
|
assert Conn.get_resp_header(conn, "content-type") == ["video/mp4"]
|
||||||
|
assert conn.resp_body == "test"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "replaces application type", %{conn: conn} do
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "/content"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "application/activity+json"}],
|
||||||
|
body: "test"
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
conn = ReverseProxy.call(Map.put(conn, :method, "GET"), "/content")
|
||||||
|
|
||||||
|
assert conn.status == 200
|
||||||
|
assert Conn.get_resp_header(conn, "content-type") == ["application/octet-stream"]
|
||||||
|
assert conn.resp_body == "test"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue