Page MenuHomePhorge

No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None
diff --git a/test/pleroma/web/plugs/instance_static_test.exs b/test/pleroma/web/plugs/instance_static_test.exs
index 017c49d1e..b5a5a3334 100644
--- a/test/pleroma/web/plugs/instance_static_test.exs
+++ b/test/pleroma/web/plugs/instance_static_test.exs
@@ -1,183 +1,140 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.InstanceStaticTest do
use Pleroma.Web.ConnCase
@dir "test/tmp/instance_static"
setup do
Pleroma.Backports.mkdir_p!(@dir)
on_exit(fn -> File.rm_rf(@dir) end)
end
setup do: clear_config([:instance, :static_dir], @dir)
test "overrides index" do
bundled_index = get(build_conn(), "/")
refute html_response(bundled_index, 200) == "hello world"
File.write!(@dir <> "/index.html", "hello world")
index = get(build_conn(), "/")
assert html_response(index, 200) == "hello world"
end
test "also overrides frontend files", %{conn: conn} do
name = "pelmora"
ref = "uguu"
clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
bundled_index = get(conn, "/")
refute html_response(bundled_index, 200) == "from frontend plug"
path = "#{@dir}/frontends/#{name}/#{ref}"
Pleroma.Backports.mkdir_p!(path)
File.write!("#{path}/index.html", "from frontend plug")
index = get(conn, "/")
assert html_response(index, 200) == "from frontend plug"
File.write!(@dir <> "/index.html", "from instance static")
index = get(conn, "/")
assert html_response(index, 200) == "from instance static"
end
test "overrides any file in static/static" do
bundled_index = get(build_conn(), "/static/terms-of-service.html")
assert html_response(bundled_index, 200) ==
File.read!("priv/static/static/terms-of-service.html")
File.mkdir!(@dir <> "/static")
File.write!(@dir <> "/static/terms-of-service.html", "plz be kind")
index = get(build_conn(), "/static/terms-of-service.html")
assert html_response(index, 200) == "plz be kind"
File.write!(@dir <> "/static/kaniini.html", "<h1>rabbit hugs as a service</h1>")
index = get(build_conn(), "/static/kaniini.html")
assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
end
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\"}")
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
# The content should be served, but with a sanitized content-type
content_type =
Enum.find_value(conn.resp_headers, fn
{"content-type", value} -> value
_ -> nil
end)
# It should have been sanitized to application/octet-stream because "application"
# is not in the allowed_mime_types list
assert content_type == "application/octet-stream"
# Create a file with an allowed extension (.jpg)
File.write!(@dir <> "/emoji/safe.jpg", "fake image data")
# Request the safe file
conn = get(build_conn(), "/emoji/safe.jpg")
# Verify the file was served (status 200)
assert conn.status == 200
# Get the content-type
content_type =
Enum.find_value(conn.resp_headers, fn
{"content-type", value} -> value
_ -> nil
end)
# It should be preserved because "image" is in the allowed_mime_types list
assert content_type == "image/jpeg"
end
-
- describe "404s for missing files in static-only paths" do
- test "returns 404 for non-existent static-only JSON files" do
- conn = get(build_conn(), "/static/non-existent.json")
-
- assert conn.status == 404
- assert ["application/json"] = get_resp_header(conn, "content-type")
- assert Jason.decode!(conn.resp_body) == %{"error" => "not found"}
- end
-
- test "returns 404 for non-existent static-only non-JSON files" do
- conn = get(build_conn(), "/static/non-existent.txt")
-
- assert conn.status == 404
- assert conn.resp_body == "Not found"
- assert ["text/plain"] = get_resp_header(conn, "content-type")
- end
-
- test "returns 404 for non-existent .css files" do
- conn = get(build_conn(), "/static/non-existent.css")
-
- assert conn.status == 404
- assert conn.resp_body == "Not found"
- # Verifies that we forced text/plain for the error body, even though the path was .css
- assert ["text/plain"] = get_resp_header(conn, "content-type")
- end
-
- test "returns 404 for non-existent files without an extension" do
- conn = get(build_conn(), "/static/non-existent")
-
- assert conn.status == 404
- assert conn.resp_body == "Not found"
- assert ["text/plain"] = get_resp_header(conn, "content-type")
- end
-
- test "returns 200 (falls through to SPA) for non-static-only paths" do
- # /some-route is NOT in static_only_files, so it should still fall through to the SPA.
- conn = get(build_conn(), "/some-route")
-
- assert conn.status == 200
- assert ["text/html; charset=utf-8"] = get_resp_header(conn, "content-type")
- end
- end
end
diff --git a/test/pleroma/web/plugs/static_not_found_plug_test.exs b/test/pleroma/web/plugs/static_not_found_plug_test.exs
new file mode 100644
index 000000000..a5d063c53
--- /dev/null
+++ b/test/pleroma/web/plugs/static_not_found_plug_test.exs
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+defmodule Pleroma.Web.Plugs.StaticNotFoundPlugTest do
+ use Pleroma.Web.ConnCase
+
+ describe "404s for missing files in static-only paths" do
+ test "returns 404 for non-existent static-only JSON files" do
+ conn = get(build_conn(), "/static/non-existent.json")
+
+ assert conn.status == 404
+ assert ["application/json"] = get_resp_header(conn, "content-type")
+ assert Jason.decode!(conn.resp_body) == %{"error" => "not found"}
+ end
+
+ test "returns 404 for non-existent static-only non-JSON files" do
+ conn = get(build_conn(), "/static/non-existent.txt")
+
+ assert conn.status == 404
+ assert conn.resp_body == "Not found"
+ assert ["text/plain"] = get_resp_header(conn, "content-type")
+ end
+
+ test "returns 404 for non-existent .css files" do
+ conn = get(build_conn(), "/static/non-existent.css")
+
+ assert conn.status == 404
+ assert conn.resp_body == "Not found"
+ # Verifies that we forced text/plain for the error body, even though the path was .css
+ assert ["text/plain"] = get_resp_header(conn, "content-type")
+ end
+
+ test "returns 404 for non-existent files without an extension" do
+ conn = get(build_conn(), "/static/non-existent")
+
+ assert conn.status == 404
+ assert conn.resp_body == "Not found"
+ assert ["text/plain"] = get_resp_header(conn, "content-type")
+ end
+
+ test "returns 200 (falls through to SPA) for non-static-only paths" do
+ # /some-route is NOT in static_only_files, so it should still fall through to the SPA.
+ conn = get(build_conn(), "/some-route")
+
+ assert conn.status == 200
+ assert ["text/html; charset=utf-8"] = get_resp_header(conn, "content-type")
+ end
+ end
+end

File Metadata

Mime Type
text/x-diff
Expires
Fri, Sep 18, 11:45 PM (5 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1768485
Default Alt Text
(8 KB)

Event Timeline