Authors
perillamint
Description
Denial of Service attack through Mastodon HTTP signature validation.
Affected software / version
All currently supported Mastodon version (suspects)
Severity
CVSS v3.1 score: 7.5 (High)
Vector String: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Detailed information
When Mastodon has to verify the actor is eligible to fetch the status, Mastodon parses the request header and
- Tries to retrieve the signing key from the remote actor
- Validate the actor through Webfinger request
During this process, maliciously crafted servers intentionally delay communication to the victim server and can hold the connection for up to 20 seconds by delaying both responses right before timeout.
An attacker can leverage this to fill up the web pool. It directly leads to the slowloris-type denial-of-service attack.
Proof-of-Concept code
[ RESTRICTED INFORMATION ]
Possible mitigation
Mastodon server administrators
No full mitigation exists.
You will have to defend against following API endpoints
- shared inbox
- user inbox
- private posts (followers only, mentioned peoples only)
- If you enabled
AUTHORIZED_FETCH
, every ActivityPub API endpoint will be affected.
Mastodon code maintainers
- Validate actor eligibility through key ID before fetching the key
- Rate limit the number of actor creation per public suffix
- Apply concurrent connection limit per IP address on ActivityPub requests (may problematic on communication between large instances)
- Reduce the timeout value (not recommended)
… or to fix it fundermentally (and gain extra performance boost) …
- Heavily modify RoR and its dependency to somehow make the HTTP signature validation process asynchronous.
- Rewrite it in Rust
- Jokes aside, at least, rewrite it in a language that supports asynchronous I/O well.
Notes
This attack scenario also can happen in normal situations. It is much like a performance issue rather then proper “vulnerability” but severe enough to make it a vulnerability.
For example, if one server A decides to cease operation and runs self-destruct script, it will
- Spam
DELETE
activity to all servers that it knows.
A relatively new server B that does not know lots of accounts of the server A
will try to validate the HTTP request it received in the /inbox
endpoint.
It will
- Attempt to fetch the signing key from the remote server A
- Attempt to validate the actor through Webfinger request to server A
And if the server A is not responding, it will wait for the timeout (up to 10 sec for each sub-operation)
If the server A sends lots of DELETE
activities but struggles to answer the
key request fast enough, it will eventually fill up the web pool of server B
and make it unresponsive.
Amendment
OK, I know RIIR / “write in a different language” is impractical. It is just there because I need little bit of joke option while writing this document.
To compare Mastodon with other implementation, Misskey, which is immune to this kind of vulnerability due to its nature (ofc, it has its own performance issue, but that is another topic), does not lock up while fetching a remote actor.
However, Mastodon does. It isn’t just a vulnerability but directly related to usability issue on small scale deployments choose not to autoscale because of its corresponding costs. It is a clearly horrible performance issue can abused to DoS an instance AND hurt user experience in some conditions described in Notes section.
References
N/A
Disclosure timeline
Timestamp | Comment |
---|---|
2023-07-19T01:00Z | Exploit idea emerged. |
2023-07-19T13:00Z | First Proof-of-Concept developed and tested against Mastodon 4.1.2 |
2023-07-19T14:23Z | Proof-of-Concept tested against 4.1.3 |
2023-07-20T09:36Z | Report written and sent to security@joinmastodon.org |
2023-07-20T09:54Z | File proof published at https://social.silicon.moe/@perillamint/110745803938940887 |
2023-08-05T10:55Z | Contacted again through security@joinmastodon.org |
2023-08-08T03:01Z | Received acknowledgement from Mastodon gGmbH |
2023-09-19T20:23Z | Sent reminder email to security@joinmastodon.org (No response yet) |
2023-10-18T09:36Z | Responsible disclusure deadline |
2023-10-18T09:37Z | Public disclosure |