Signature Verification in WordPress

TLDR: Without signature verification, sites using the plugin are wide open to impersonation attacks.

I’ve been developing federated comments for the ActivityPub plugin, but before getting it merged, I thought it was essential to implement HTTP Signature Verification.


Because without signature verification, ActivityPub servers would be wide open to impersonation attacks.

Screenshot of the Moderation page showing forged comments from and
Some forged comments (IP address is the giveaway)

How does it Work?

Server to server federation is authenticated using HTTP Signatures in conjunction with the signing key from the actor’s publicKey field. The keyId should link to the actor so that the publicKey field can be retrieved. At minimum, the digest field should be included in the set of headers being signed.

Trust & Safety

One feature I was keen support is Authorized Fetch, this is a privacy feature that requires remote servers fetching content to also provide HTTP signatures, thereby preventing unauthorized or blocked servers from accessing public posts (at least over the protocol).

While developing support for Authorized fetch, I realized we could make also support an Application actor, which lead to how we could also have a blog-wide actor. Which was a much requested feature!

Developer Note

When developing this feature you will likely be doing so from a local machine and using some type of tunnel, such as ngrok, also its hard to tell what type of setup your software will be deployed on, so don’t forget to include a check for x_original_host header


Special thanks again to @mikedev for providing a starting point to the signatures code. To @pfefferle for helping the PR over the finish line with Tests

Also to WDS for supporting a part of this work via

One response to “Signature Verification in WordPress”

  1. dev Avatar

    Addedum: shout out to @darius for their activitypub test tool, as visible in the above screenshot!

Leave a Reply

Your email address will not be published. Required fields are marked *