mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2025-03-12 14:43:03 +00:00
InstanceStatic: Extra-sanitize emoji
This commit is contained in:
parent
b1309bdb40
commit
d9ae9b676c
3 changed files with 50 additions and 18 deletions
|
@ -66,7 +66,7 @@ config :pleroma, Pleroma.Upload,
|
|||
filename_display_max_length: 30,
|
||||
default_description: nil,
|
||||
base_url: nil,
|
||||
allowed_mime_types: ["image", "audio", "video", "text"]
|
||||
allowed_mime_types: ["image", "audio", "video"]
|
||||
|
||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads"
|
||||
|
||||
|
|
|
@ -51,25 +51,25 @@ defmodule Pleroma.Web.Plugs.InstanceStatic do
|
|||
|> Map.put(:from, from)
|
||||
|> Map.put(:content_types, false)
|
||||
|
||||
# Get sanitized content type before calling Plug.Static
|
||||
# Include "text" to allow HTML files and other text-based content
|
||||
allowed_mime_types =
|
||||
Pleroma.Config.get([Pleroma.Upload, :allowed_mime_types], [
|
||||
"image",
|
||||
"audio",
|
||||
"video",
|
||||
"text"
|
||||
])
|
||||
|
||||
conn = set_content_type(conn, %{allowed_mime_types: allowed_mime_types}, conn.request_path)
|
||||
conn = set_content_type(conn, conn.request_path)
|
||||
|
||||
# Call Plug.Static with our sanitized content-type
|
||||
Plug.Static.call(conn, opts)
|
||||
end
|
||||
|
||||
defp set_content_type(conn, opts, filepath) do
|
||||
defp set_content_type(conn, "/emoji/" <> filepath) do
|
||||
real_mime = MIME.from_path(filepath)
|
||||
clean_mime = Pleroma.Web.Plugs.Utils.get_safe_mime_type(opts, real_mime)
|
||||
|
||||
clean_mime =
|
||||
Pleroma.Web.Plugs.Utils.get_safe_mime_type(%{allowed_mime_types: ["image"]}, real_mime)
|
||||
|
||||
put_resp_header(conn, "content-type", clean_mime)
|
||||
end
|
||||
|
||||
defp set_content_type(conn, filepath) do
|
||||
real_mime = MIME.from_path(filepath)
|
||||
put_resp_header(conn, "content-type", real_mime)
|
||||
end
|
||||
end
|
||||
|
||||
# I think this needs to be uncleaned except for emoji.
|
||||
|
|
|
@ -63,15 +63,47 @@ defmodule Pleroma.Web.Plugs.InstanceStaticTest do
|
|||
assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
|
||||
end
|
||||
|
||||
test "sanitizes content-types for potentially dangerous file extensions" do
|
||||
test "does not sanitize dangerous files in general, as there can be html and javascript files legitimately in this folder" do
|
||||
# Create a file with a potentially dangerous extension (.json)
|
||||
# This mimics an attacker trying to serve ActivityPub JSON with a static file
|
||||
File.mkdir!(@dir <> "/static")
|
||||
File.write!(@dir <> "/static/malicious.json", "{\"type\": \"ActivityPub\"}")
|
||||
|
||||
# Request the malicious file
|
||||
conn = get(build_conn(), "/static/malicious.json")
|
||||
|
||||
assert conn.status == 200
|
||||
|
||||
content_type =
|
||||
Enum.find_value(conn.resp_headers, fn
|
||||
{"content-type", value} -> value
|
||||
_ -> nil
|
||||
end)
|
||||
|
||||
assert content_type == "application/json"
|
||||
|
||||
File.write!(@dir <> "/static/safe.jpg", "fake image data")
|
||||
|
||||
conn = get(build_conn(), "/static/safe.jpg")
|
||||
|
||||
assert conn.status == 200
|
||||
|
||||
# Get the content-type
|
||||
content_type =
|
||||
Enum.find_value(conn.resp_headers, fn
|
||||
{"content-type", value} -> value
|
||||
_ -> nil
|
||||
end)
|
||||
|
||||
assert content_type == "image/jpeg"
|
||||
end
|
||||
|
||||
test "always sanitizes emojis to images" do
|
||||
File.mkdir!(@dir <> "/emoji")
|
||||
File.write!(@dir <> "/emoji/malicious.html", "<script>HACKED</script>")
|
||||
|
||||
# Request the malicious file
|
||||
conn = get(build_conn(), "/emoji/malicious.html")
|
||||
|
||||
# Verify the file was served (status 200)
|
||||
assert conn.status == 200
|
||||
|
||||
|
@ -87,10 +119,10 @@ defmodule Pleroma.Web.Plugs.InstanceStaticTest do
|
|||
assert content_type == "application/octet-stream"
|
||||
|
||||
# Create a file with an allowed extension (.jpg)
|
||||
File.write!(@dir <> "/static/safe.jpg", "fake image data")
|
||||
File.write!(@dir <> "/emoji/safe.jpg", "fake image data")
|
||||
|
||||
# Request the safe file
|
||||
conn = get(build_conn(), "/static/safe.jpg")
|
||||
conn = get(build_conn(), "/emoji/safe.jpg")
|
||||
|
||||
# Verify the file was served (status 200)
|
||||
assert conn.status == 200
|
||||
|
|
Loading…
Reference in a new issue