fix: Refetch user keys when HTTP Signature validation fails
Co-authored-by: Erin Shepherd <erin.shepherd@e43.eu>
This commit is contained in:
parent
bdf3311402
commit
c4ec2d0942
@ -95,11 +95,25 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HTTP-Signatureの検証
|
// HTTP-Signatureの検証
|
||||||
const httpSignatureValidated = httpSignature.verifySignature(
|
let httpSignatureValidated = httpSignature.verifySignature(
|
||||||
signature,
|
signature,
|
||||||
authUser.key.keyPem,
|
authUser.key.keyPem,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If signature validation failed, try refetching the actor
|
||||||
|
if (!httpSignatureValidated) {
|
||||||
|
authUser.key = await dbResolver.refetchPublicKeyForApId(authUser.user);
|
||||||
|
|
||||||
|
if (authUser.key == null) {
|
||||||
|
return "skip: failed to re-resolve user publicKey";
|
||||||
|
}
|
||||||
|
|
||||||
|
httpSignatureValidated = httpSignature.verifySignature(
|
||||||
|
signature,
|
||||||
|
authUser.key.keyPem,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// また、signatureのsignerは、activity.actorと一致する必要がある
|
// また、signatureのsignerは、activity.actorと一致する必要がある
|
||||||
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
|
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
|
||||||
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
||||||
|
@ -86,11 +86,25 @@ export async function checkFetch(req: IncomingMessage): Promise<number> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HTTP-Signatureの検証
|
// HTTP-Signatureの検証
|
||||||
const httpSignatureValidated = httpSignature.verifySignature(
|
let httpSignatureValidated = httpSignature.verifySignature(
|
||||||
signature,
|
signature,
|
||||||
authUser.key.keyPem,
|
authUser.key.keyPem,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If signature validation failed, try refetching the actor
|
||||||
|
if (!httpSignatureValidated) {
|
||||||
|
authUser.key = await dbResolver.refetchPublicKeyForApId(authUser.user);
|
||||||
|
|
||||||
|
if (authUser.key == null) {
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
|
||||||
|
httpSignatureValidated = httpSignature.verifySignature(
|
||||||
|
signature,
|
||||||
|
authUser.key.keyPem,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!httpSignatureValidated) {
|
if (!httpSignatureValidated) {
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ import { Cache } from "@/misc/cache.js";
|
|||||||
import { uriPersonCache, userByIdCache } from "@/services/user-cache.js";
|
import { uriPersonCache, userByIdCache } from "@/services/user-cache.js";
|
||||||
import type { IObject } from "./type.js";
|
import type { IObject } from "./type.js";
|
||||||
import { getApId } from "./type.js";
|
import { getApId } from "./type.js";
|
||||||
import { resolvePerson } from "./models/person.js";
|
import { resolvePerson, updatePerson } from "./models/person.js";
|
||||||
|
|
||||||
|
|
||||||
const publicKeyCache = new Cache<UserPublickey | null>("publicKey", 60 * 30);
|
const publicKeyCache = new Cache<UserPublickey | null>("publicKey", 60 * 30);
|
||||||
const publicKeyByUserIdCache = new Cache<UserPublickey | null>(
|
const publicKeyByUserIdCache = new Cache<UserPublickey | null>(
|
||||||
@ -151,7 +152,7 @@ export default class DbResolver {
|
|||||||
*/
|
*/
|
||||||
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
||||||
user: CacheableRemoteUser;
|
user: CacheableRemoteUser;
|
||||||
key: UserPublickey;
|
key: UserPublickey | null;
|
||||||
} | null> {
|
} | null> {
|
||||||
const key = await publicKeyCache.fetch(
|
const key = await publicKeyCache.fetch(
|
||||||
keyId,
|
keyId,
|
||||||
@ -203,4 +204,13 @@ export default class DbResolver {
|
|||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async refetchPublicKeyForApId(user: CacheableRemoteUser): Promise<UserPublickey | null> {
|
||||||
|
await updatePerson(user.uri!, undefined, undefined, user);
|
||||||
|
let key = await UserPublickeys.findOneBy({ userId: user.id });
|
||||||
|
if (key != null) {
|
||||||
|
await publicKeyByUserIdCache.set(user.id, key);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user