Changeset f85b2c3 in Klonkt
- Timestamp:
- 08/07/2026 05:00:09 PM (5 weeks ago)
- Branches:
- main
- Children:
- 952baf3
- Parents:
- 12bed59
- Files:
-
- 1 added
- 1 edited
-
src/services/ActivityPubService.js (modified) (1 diff)
-
test/ap-signature-keyid-binding.test.js (added)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r12bed59 rf85b2c3 1238 1238 const pem = actor && actor.publicKey && actor.publicKey.publicKeyPem; 1239 1239 if (!pem) return null; 1240 // Bind the key to the actor it speaks for. Without this we hand back whatever 1241 // `id` the fetched document claims, so anyone could host a document carrying a 1242 // VICTIM's id next to their OWN public key, sign with their own private half, 1243 // and be believed: the victim's server is never contacted. The caller decides on 1244 // `verified.id`, so the identity has to come from where the key was FETCHED, 1245 // never from what the document says about itself. 1246 // Adds conditions only, and there is no exemption list on purpose: an 1247 // "unless it's a known peer" escape hatch is exactly the door this closes. 1248 // Note this does not narrow what we accept in practice, since the line above 1249 // already requires the embedded publicKey object (an array or a bare URI 1250 // reference never worked here). 1251 const key = actor.publicKey; 1252 try { 1253 if (new URL(p.keyId).host !== new URL(actor.id).host) return null; // same origin as the key 1254 if (key.id && key.id !== p.keyId) return null; // this key, not a neighbour's 1255 if (key.owner && key.owner !== actor.id) return null; // and it belongs to this actor 1256 } catch { return null; } // unparseable id or keyId 1240 1257 const hs = (p.headers || '(request-target) host date').split(/\s+/); 1241 1258 // Behind a reverse proxy the raw Host header is the backend bind (e.g. localhost:3000, when
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)