Hey there, quite an important one for you here today. We’ve got ourself a vulnerability and it’s time to make like a tree and patch. Not sure what that means but that’s neither here nor there.
I won’t drone on, let’s get to the interesting stuff
if you don’t care about details and just want to cover yourself, skip down to “Updating”
New stuff
Security Fixes
The big things:
Content-Type
headers are sanitised for emoji, proxied files and user uploads fromLocalUploader
, in particular it’s no longer possible to make Akkoma serve such files as ActivityPub objects- fetched ActivityPub object now need strict id/url matches
These two enabled impersonation other users and likely affect every AP-capable version of *oma ever, so do upgrade now!
But there’s more:
- new CLI tasks to best-effort check if impersonation was done or attempted (this won’t get 100% of things, but will look for what we expect to see if anyone actually found this before us)
- when fetching AP objects cross-domain redirects are now disallowed; it is no longer possible for the final destination domain to pose as the initial fetch domain (e.g.
media.akkoma.dev
pretending to beotp.akkoma.dev
) - some proactive hardening against any more path traversal attacks in emoji handling (no known exploit)
- tighter checks for user objects
- URLs of stolen emoji from
StealEmoji
are no longer predictable - refetched objects can no longer attribute themselves to foreign actor
Other
- dropped the same-domain default for media proxy and local uploader (see upgrade notes)
- StealEmoji
- will avoid downloading too large files if the remote sends a
Content-Length
header - will by default not download files whose size can’t be queried ahead of time (see cheatsheet if you want to re-enable this)
- now uses pack.json format (see upgrade notes)
- as a result now works with all image types out of the box
- only steals shortcodes we actually recognise as valid ourselves (this mostly means alphanumeric, the same restrictions you’re used to when uploading emoji)
- will avoid downloading too large files if the remote sends a
- the
Dedupe
upload filter is now always enabled AnonymizeFilenames
is again opt-in
Updating
First follow the usual steps; if upgrading from 3.11.0 there are no DB migrations or frontend changes.
https://docs.akkoma.dev/stable/administration/updating/
But before you startup the instance some manual changes may be needed depending on your (past) config.
Explicit upload and media proxy domains
If you haven’t explicitly configured the base_url
s already and are using the features, you’ll need to do so now. E.g. if your main instance is on example.com
the config needs to contain something like this:
Whilst it is still possible to keep media proxy/uploads on the same domain, we massively encourage you to change that ASAP!!!
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "example.com", scheme: "https", port: 443],
...
# TODO: migrate to a subdomain!
config :pleroma, Pleroma.Upload,
base_url: "http://example.com/media/", #the /media/ here is important!
...
# TODO: migrate to a subdomain!
config :pleroma, :media_proxy,
base_url: "https://example.com",
...
Converting stolen emoji to pack.json format
If you’re using or used StealEmoji
in the past, some manual intervention is needed to carry existing emoji over to the new pack.json format. Create a new script file in e.g. the repo root and insert the following:
#!/bin/sh
# SPDX-License-Identifier: CC0-1.0 or 0BSD
set -eu
DIR="${DIR:-$(dirname "$0")/instance/static/emoji/stolen/}"
ALLOWED_EXT="${ALLOWED_EXT:-.png .gif}"
echo "Converting '$DIR' to pack.json..." >&2
cd "$DIR"
exec > pack.json
printf '{
"pack": {
"can-download": false,
"share-files": false,
"description": "Collection of emoji auto-stolen from other instances"
},
"files": {
'
count=0
for ext in $ALLOWED_EXT ; do
for f in *"$ext" ; do
if [ "${f%.*}" = "*" ] ; then
continue
fi
f="$(echo "$f" | sed -e 's/"/\\"/g')"
[ "$count" -gt 0 ] && printf ',\n'
printf ' "%s": "%s"' "${f%.*}" "$f"
count="$((count + 1))"
done
done
printf '
},
"files_count": %d
}
' "$count"
echo "Done." >&2
Now check the setting of :pleroma, :emoji, :pack_extensions
and where stolen emoji are stored. E.g. if :pack_extensions
is set to ["*.png", "*.gif", "*.jpg"]
and your stolen emoji are at /var/lib/akkoma/instance/emoji/stolen
run the script as the akkoma user like:
ALLOWED_EXT=".png .gif .jpg" DIR="/var/lib/akkoma/instance/emoji/stolen" sh ./convert_pack.sh
If you didn’t set :emoji, :pack_extensions
yourself, just drop the ALLOWED_EXT="..."
prefix.
Starting up
You’re now ready to start up the instance again.
Post-Upgrade Steps
checking for impersonation (attempts)
Two new CLI tasks got added to check if your instance was ever used for impersonation or fell for any counterfeit messages. You should probably run those and let others know if any real abuse was found. Detection (esp of inserted remote counterfeits) is not perfect, read the notes in the task output and reexamine possible matches!
See their docs for how to run them.
media subdomain
Going forward same-domain setups are still supported but strongly discouraged. For now continuing to use the same domain is ok since all known exploits are fixed, but you probably should migrate to a subdomain when you can.
The old guide from Mitigating the recent Pleroma issues mostly still applies, but:
- don’t redirect
/proxy/
from the main domain, return404
instead - there’s no need to manually set response headers
You can also take a look at the newly updated example nginx config for reference and if you use Caddy see also this thread. We might write a self-contained migration guide in the future.
Was my instance vulnerable?
Almost certainly, yes you were.
Who could place payloads for impersonating users from your instance depends on config:
- always: authors of emoji packs added to your instance (if you didn’t check pack contents ahead of time)
Note: the payloads need special adjustment for each instance though - using local uploader?: any other local user if uploads are on the same domain or used to be on the same domain and a redirect was left in place
- using StealEmoji?: anyone with emoji management rights on an explicitly allowed host
- using media proxy?: anyone who can send a post to your instance and then retrieve the proxied link from your instance (e.g. via scrolling through the global timeline)
Once a payload was placed, counterfeit insertion into any *oma instance (or others with lax id checks) can be triggered by either anyone with access to search for remote content or anyone allowed to send AP objects to your instance (which can reference the local payload e.g. in inReplyTo
).
There is no workaround for this and the only mitigation is updating asap.
One massive thanky
All of my concievable thanks, from the percievable to the theoretical, go to Oneric on akko.wtf
This was discovered by them and mitigated by them, and they even handled synchronisation with some other projects. I cannot emphasize enough how helpful they have been. Thank you.