akkoma/test/pleroma/emoji/pack_test.exs
Oneric ddd79ff22d Proactively harden emoji pack against path traversal
No new path traversal attacks are known. But given the many entrypoints
and code flow complexity inside pack.ex, it unfortunately seems
possible a future refactor or addition might reintroduce one.
Furthermore, some old packs might still contain traversing path entries
which could trigger undesireable actions on rename or delete.

To ensure this can never happen, assert safety during path construction.

Path.safe_relative was introduced in Elixir 1.14, but
fortunately, we already require at least 1.14 anyway.
2024-03-18 22:33:10 -01:00

102 lines
2.9 KiB
Elixir

# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emoji.PackTest do
use Pleroma.DataCase, async: false
alias Pleroma.Emoji.Pack
@static_dir Pleroma.Config.get!([:instance, :static_dir])
@emoji_path Path.join(
Pleroma.Config.get!([:instance, :static_dir]),
"emoji"
)
setup do
pack_path = Path.join(@emoji_path, "dump_pack")
File.mkdir_p!(pack_path)
clear_config([:instance, :static_dir], @static_dir)
File.write!(Path.join(pack_path, "pack.json"), """
{
"files": { },
"pack": {
"description": "Dump pack", "homepage": "https://pleroma.social",
"license": "Test license", "share-files": true
}}
""")
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("dump_pack")
on_exit(fn ->
File.rm_rf!(pack_path)
end)
{:ok, pack: pack}
end
describe "add_file/4" do
test "add emojis from zip file", %{pack: pack} do
file = %Plug.Upload{
content_type: "application/zip",
filename: "emojis.zip",
path: Path.absname("test/fixtures/emojis.zip")
}
{:ok, updated_pack} = Pack.add_file(pack, nil, nil, file)
assert updated_pack.files == %{
"a_trusted_friend-128" => "128px/a_trusted_friend-128.png",
"auroraborealis" => "auroraborealis.png",
"baby_in_a_box" => "1000px/baby_in_a_box.png",
"bear" => "1000px/bear.png",
"bear-128" => "128px/bear-128.png"
}
assert updated_pack.files_count == 5
end
end
test "returns error when zip file is bad", %{pack: pack} do
file = %Plug.Upload{
content_type: "application/zip",
filename: "emojis.zip",
path: Path.absname("test/instance_static/emoji/test_pack/blank.png")
}
assert Pack.add_file(pack, nil, nil, file) == {:error, :einval}
end
test "returns pack when zip file is empty", %{pack: pack} do
file = %Plug.Upload{
content_type: "application/zip",
filename: "emojis.zip",
path: Path.absname("test/fixtures/empty.zip")
}
{:ok, updated_pack} = Pack.add_file(pack, nil, nil, file)
assert updated_pack == pack
end
test "add emoji file", %{pack: pack} do
file = %Plug.Upload{
filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png"
}
{:ok, updated_pack} = Pack.add_file(pack, "test_blank", "test_blank.png", file)
assert updated_pack.files == %{
"test_blank" => "test_blank.png"
}
assert updated_pack.files_count == 1
end
test "load_pack/1 panics on path traversal in a forged pack name" do
assert_raise(RuntimeError, "Invalid or malicious pack name: ../../../../../dump_pack", fn ->
Pack.load_pack("../../../../../dump_pack")
end)
end
end