fix: Refetch user keys when HTTP Signature validation fails
If a user has had a key rotation, and nobody on this server follows that user, we will not receive the Update activity with the new key Therefore, when we encounter key validation errors we should check for an up-to-date key. References (other implementations): * [Mastodon](https://github.com/mastodon/mastodon/blob/fc9ab61448af94513524f14f5fd287d2a26ceeab/app/controllers/concerns/signature_verification.rb#L96) * [Akkoma](https://akkoma.dev/AkkomaGang/http_signatures/src/branch/main/lib/http_signatures/http_signatures.ex#L46)
This commit is contained in:
@@ -164,6 +164,19 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Miskey User -> Refetched Key
|
||||
*/
|
||||
@bindThis
|
||||
public async refetchPublicKeyForApId(user: MiRemoteUser): Promise<MiUserPublickey | null> {
|
||||
await this.apPersonService.updatePerson(user.uri!);
|
||||
const key = this.userPublickeysRepository.findOneBy({ userId: user.id });
|
||||
if (key != null) {
|
||||
await this.publicKeyByUserIdCache.set(user.id, key);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public dispose(): void {
|
||||
this.publicKeyCache.dispose();
|
||||
|
||||
@@ -104,7 +104,18 @@ export class InboxProcessorService {
|
||||
}
|
||||
|
||||
// HTTP-Signatureの検証
|
||||
const httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
|
||||
let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
|
||||
|
||||
// If signature validation failed, try refetching the actor
|
||||
if (!httpSignatureValidated) {
|
||||
authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user);
|
||||
|
||||
if (authUser.key == null) {
|
||||
throw new Bull.UnrecoverableError('skip: failed to re-resolve user publicKey');
|
||||
}
|
||||
|
||||
httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
|
||||
}
|
||||
|
||||
// また、signatureのsignerは、activity.actorと一致する必要がある
|
||||
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
|
||||
|
||||
Reference in New Issue
Block a user