ユーザーとキーの同一性チェックはhostの一致にする

This commit is contained in:
tamaina 2024-03-09 20:01:07 +00:00
parent 154a2026ea
commit eb8495648e

View file

@ -18,6 +18,7 @@ import { getApId } from './type.js';
import { ApPersonService } from './models/ApPersonService.js';
import { ApLoggerService } from './ApLoggerService.js';
import type { IObject } from './type.js';
import { UtilityService } from '../UtilityService.js';
export type UriParseResult = {
/** wether the URI was generated by us */
@ -56,11 +57,18 @@ export class ApDbResolverService implements OnApplicationShutdown {
private cacheService: CacheService,
private apPersonService: ApPersonService,
private apLoggerService: ApLoggerService,
private utilityService: UtilityService,
) {
this.publicKeyByUserIdCache = new MemoryKVCache<MiUserPublickey[] | null>(Infinity);
this.logger = this.apLoggerService.logger.createSubLogger('db-resolver');
}
private punyHost(url: string): string {
const urlObj = new URL(url);
const host = `${this.utilityService.toPuny(urlObj.hostname)}${urlObj.port.length > 0 ? ':' + urlObj.port : ''}`;
return host;
}
@bindThis
public parseUri(value: string | IObject): UriParseResult {
const separator = '/';
@ -137,9 +145,8 @@ export class ApDbResolverService implements OnApplicationShutdown {
* AP Actor id => Misskey User and Key
* @param uri AP Actor id
* @param keyId Key id to find. If not specified, main key will be selected.
* keyIdがURLライクの場合keyIdはuriと同一であることが期待される
* @returns
* 1. uriとkeyIdが一致しない場`null`
* 1. `null`
* 2. userが見つからない場合`{ user: null, key: null }`
* 3. keyが見つからない場合`{ user, key: null }`
*/
@ -153,20 +160,19 @@ export class ApDbResolverService implements OnApplicationShutdown {
} |
null> {
if (keyId) {
try {
const actorUrl = new URL(uri);
const keyUrl = new URL(keyId);
actorUrl.hash = '';
keyUrl.hash = '';
if (actorUrl.href !== keyUrl.href) {
// uriとkeyIdのhashなしが一致しない場合、actorと鍵の所有者が一致していないということである
// その場合、そもそも署名は有効といえないのでキーの検索は無意味
this.logger.warn(`actor uri and keyId are not matched uri=${uri} keyId=${keyId}`);
return null;
}
} catch (err) {
// キーがURLっぽくない場合はエラーになるはず。そういった場合はとりあえずキー検索してみる
this.logger.warn(`maybe actor uri or keyId are not url like: uri=${uri} keyId=${keyId}`, { err });
if (this.punyHost(uri) !== this.punyHost(keyId)) {
/**
* keyIdはURL形式かつkeyIdのホストはuriのホストと一致するはず
* ApPersonService.validateActorに由来
*
* Mastodonはリプライ関連で他人のートをHTTP Signature署名して送ってくることがある
*
* uriとkeyIdのホストが一致しない場合は無視する
* keyIdとuriの同一性を比べてみてもいいが`uri#*-key`keyIdを設定するのが
*
*/
this.logger.warn(`actor uri and keyId are not matched uri=${uri} keyId=${keyId}`);
return null;
}
}