Fix: v11で未認知ユーザーからActivityが飛んできた場合に処理できない (#4733)

* Fix: inboxに未知のユーザーが来ると処理できない

* こうかな
This commit is contained in:
MeiMei 2019-04-18 00:53:00 +09:00 committed by syuilo
parent 95733c9490
commit 55e97864bd
1 changed files with 18 additions and 46 deletions

View File

@ -35,37 +35,8 @@ export default async (job: Bull.Job): Promise<void> => {
let key: UserPublickey; let key: UserPublickey;
if (keyIdLower.startsWith('acct:')) { if (keyIdLower.startsWith('acct:')) {
const acct = parseAcct(keyIdLower.slice('acct:'.length)); logger.warn(`Old keyId is no longer supported. ${keyIdLower}`);
const host = toPunyNullable(acct.host); return;
const username = toPuny(acct.username);
if (host === null) {
logger.warn(`request was made by local user: @${username}`);
return;
}
// アクティビティ内のホストの検証
try {
ValidateActivity(activity, host);
} catch (e) {
logger.warn(e.message);
return;
}
// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const meta = await fetchMeta();
if (meta.blockedHosts.includes(host)) {
logger.info(`Blocked request: ${host}`);
return;
}
user = await Users.findOne({
usernameLower: username.toLowerCase(),
host: host
}) as IRemoteUser;
key = await UserPublickeys.findOne(user.id).then(ensure);
} else { } else {
// アクティビティ内のホストの検証 // アクティビティ内のホストの検証
const host = toPuny(new URL(signature.keyId).hostname); const host = toPuny(new URL(signature.keyId).hostname);
@ -84,19 +55,29 @@ export default async (job: Bull.Job): Promise<void> => {
return; return;
} }
key = await UserPublickeys.findOne({ const _key = await UserPublickeys.findOne({
keyId: signature.keyId keyId: signature.keyId
}).then(ensure); });
user = await Users.findOne(key.userId) as IRemoteUser; if (_key) {
// 登録済みユーザー
user = await Users.findOne(_key.userId) as IRemoteUser;
key = _key;
} else {
// 未登録ユーザーの場合はリモート解決
user = await resolvePerson(activity.actor) as IRemoteUser;
if (user == null) {
throw new Error('failed to resolve user');
}
key = await UserPublickeys.findOne(user.id).then(ensure);
}
} }
// Update Person activityの場合は、ここで署名検証/更新処理まで実施して終了 // Update Person activityの場合は、ここで署名検証/更新処理まで実施して終了
if (activity.type === 'Update') { if (activity.type === 'Update') {
if (activity.object && validActor.includes(activity.object.type)) { if (activity.object && validActor.includes(activity.object.type)) {
if (user == null) { if (!httpSignature.verifySignature(signature, key.keyPem)) {
logger.warn('Update activity received, but user not registed.');
} else if (!httpSignature.verifySignature(signature, key.keyPem)) {
logger.warn('Update activity received, but signature verification failed.'); logger.warn('Update activity received, but signature verification failed.');
} else { } else {
updatePerson(activity.actor, null, activity.object); updatePerson(activity.actor, null, activity.object);
@ -105,15 +86,6 @@ export default async (job: Bull.Job): Promise<void> => {
} }
} }
// アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
if (user == null) {
user = await resolvePerson(activity.actor) as IRemoteUser;
}
if (user == null) {
throw new Error('failed to resolve user');
}
if (!httpSignature.verifySignature(signature, key.keyPem)) { if (!httpSignature.verifySignature(signature, key.keyPem)) {
logger.error('signature verification failed'); logger.error('signature verification failed');
return; return;