Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85710362
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Sep 18, 11:45 PM (4 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1768485
Default Alt Text
(8 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment