ユーザーとキーの同一性チェックはhostの一致にする
This commit is contained in:
parent
154a2026ea
commit
eb8495648e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue