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

This commit is contained in:
tamaina 2024-03-09 20:01:07 +00:00
parent 154a2026ea
commit eb8495648e
1 changed files with 22 additions and 16 deletions

View File

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