StealEmoji: make final paths infeasible to predict

Certain attacks rely on predictable paths for their payloads.
If we weren’t so overly lax in our (id, URL) check, the current
counterfeit activity exploit would be one of those.
It seems plausible for future attacks to hinge on
or being made easier by predictable paths too.

In general, letting remote actors place arbitrary data at
a path within our domain of their choosing (sans prefix)
just doesn’t seem like a good idea.

Using fully random filenames would have worked as well, but this
is less friendly for admins checking emoji dirs.
The generated suffix should still be more than enough;
an attacker needs on average 140 trillion attempts to
correctly guess the final path.
This commit is contained in:
Oneric 2024-03-09 22:41:26 +01:00
parent ee5ce87825
commit a4fa2ec9af

View file

@ -37,7 +37,16 @@ defp load_or_create_pack() do
defp add_emoji(shortcode, extension, filedata) do defp add_emoji(shortcode, extension, filedata) do
{:ok, pack} = load_or_create_pack() {:ok, pack} = load_or_create_pack()
filename = shortcode <> "." <> extension # Make final path infeasible to predict to thwart certain kinds of attacks
# (48 bits is slighty more than 8 base62 chars, thus 9 chars)
salt =
:crypto.strong_rand_bytes(6)
|> :crypto.bytes_to_integer()
|> Base62.encode()
|> String.pad_leading(9, "0")
filename = shortcode <> "-" <> salt <> "." <> extension
Pack.add_file(pack, shortcode, filename, filedata) Pack.add_file(pack, shortcode, filename, filedata)
end end
@ -71,7 +80,7 @@ defp steal_emoji(%{} = response, {shortcode, extension}) do
e -> e ->
Logger.warning( Logger.warning(
"MRF.StealEmojiPolicy: Failed to add #{shortcode}.#{extension}: #{inspect(e)}" "MRF.StealEmojiPolicy: Failed to add #{shortcode} as #{extension}: #{inspect(e)}"
) )
nil nil