Limit instance emoji to image types
Else malicious emoji packs or our EmojiStealer MRF can put payloads into the same domain as the instance itself. Sanitising the content type should prevent proper clients from acting on any potential payload. Note, this does not affect the default emoji shipped with Akkoma as they are handled by another plug. However, those are fully trusted and thus not in needed of sanitisation.
This commit is contained in:
parent
0ec62acb9d
commit
ba558c0c24
3 changed files with 36 additions and 8 deletions
|
@ -3,8 +3,12 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.InstanceStatic do
|
defmodule Pleroma.Web.Plugs.InstanceStatic do
|
||||||
|
import Plug.Conn
|
||||||
|
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
|
||||||
|
alias Pleroma.Web.Plugs.Utils
|
||||||
|
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
This is a shim to call `Plug.Static` but with runtime `from` configuration.
|
This is a shim to call `Plug.Static` but with runtime `from` configuration.
|
||||||
|
|
||||||
|
@ -43,11 +47,25 @@ def call(conn, _) do
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
|
|
||||||
defp call_static(conn, opts, from) do
|
defp set_static_content_type(conn, "/emoji/" <> _ = request_path) do
|
||||||
|
real_mime = MIME.from_path(request_path)
|
||||||
|
safe_mime = Utils.get_safe_mime_type(%{allowed_mime_types: ["image"]}, real_mime)
|
||||||
|
|
||||||
|
put_resp_header(conn, "content-type", safe_mime)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp set_static_content_type(conn, request_path) do
|
||||||
|
put_resp_header(conn, "content-type", MIME.from_path(request_path))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp call_static(%{request_path: request_path} = conn, opts, from) do
|
||||||
opts =
|
opts =
|
||||||
opts
|
opts
|
||||||
|> Map.put(:from, from)
|
|> Map.put(:from, from)
|
||||||
|
|> Map.put(:set_content_type, false)
|
||||||
|
|
||||||
Plug.Static.call(conn, opts)
|
conn
|
||||||
|
|> set_static_content_type(request_path)
|
||||||
|
|> Pleroma.Web.Plugs.StaticNoCT.call(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.Plugs.UploadedMedia do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
alias Pleroma.Web.Plugs.Utils
|
||||||
|
|
||||||
@behaviour Plug
|
@behaviour Plug
|
||||||
# no slashes
|
# no slashes
|
||||||
|
@ -76,14 +77,9 @@ defp media_is_banned(_, {:url, url}), do: MediaProxy.in_banned_urls(url)
|
||||||
|
|
||||||
defp media_is_banned(_, _), do: false
|
defp media_is_banned(_, _), do: false
|
||||||
|
|
||||||
defp get_safe_mime_type(%{allowed_mime_types: allowed_mime_types} = _opts, mime) do
|
|
||||||
[maintype | _] = String.split(mime, "/", parts: 2)
|
|
||||||
if maintype in allowed_mime_types, do: mime, else: "application/octet-stream"
|
|
||||||
end
|
|
||||||
|
|
||||||
defp set_content_type(conn, opts, filepath) do
|
defp set_content_type(conn, opts, filepath) do
|
||||||
real_mime = MIME.from_path(filepath)
|
real_mime = MIME.from_path(filepath)
|
||||||
clean_mime = get_safe_mime_type(opts, real_mime)
|
clean_mime = Utils.get_safe_mime_type(opts, real_mime)
|
||||||
put_resp_header(conn, "content-type", clean_mime)
|
put_resp_header(conn, "content-type", clean_mime)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
14
lib/pleroma/web/plugs/utils.ex
Normal file
14
lib/pleroma/web/plugs/utils.ex
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Akkoma: Magically expressive social media
|
||||||
|
# Copyright © 2024 Akkoma Authors <https://akkoma.dev>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Plugs.Utils do
|
||||||
|
@moduledoc """
|
||||||
|
Some helper functions shared across several plugs
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_safe_mime_type(%{allowed_mime_types: allowed_mime_types} = _opts, mime) do
|
||||||
|
[maintype | _] = String.split(mime, "/", parts: 2)
|
||||||
|
if maintype in allowed_mime_types, do: mime, else: "application/octet-stream"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue