fix(backend): skip inbox activities without an actor instead of throwing TypeError#17558
fix(backend): skip inbox activities without an actor instead of throwing TypeError#17558sasagar wants to merge 1 commit into
Conversation
…ing TypeError - guard getApId() against null/undefined (and fix the 'detemine' typo) - skip actor-less inbox activities early with Bull.UnrecoverableError Fixes misskey-dev#17557
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #17558 +/- ##
===========================================
- Coverage 24.87% 16.94% -7.94%
===========================================
Files 1161 1161
Lines 39629 39631 +2
Branches 11041 11042 +1
===========================================
- Hits 9859 6714 -3145
- Misses 23849 26284 +2435
- Partials 5921 6633 +712 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
このPRによるapi.jsonの差分 |
Backend memory usage comparisonBefore GC
After GC
After Request
|
…ing TypeError Backport of misskey-dev#17558 to the ikaskey fork. - guard getApId() against null/undefined - skip actor-less inbox activities early with Bull.UnrecoverableError Release v2026.5.4-ikaskey-c
|
IActivity.actor 自体はnonNullに定義されていますが、これは型定義を修正すべきでしょうか? |
|
もしくは不正な形式のジョブデータをそもそもジョブキューに積むべきではないかもしれません |
|
ありがとうございます。2点ともおっしゃる通りで、根本は inbox エンドポイントの request.body as IActivity(ActivityPubServerService)という未検証キャストだと思います。信頼できない入力を検証せず IActivity と見なしてキュー投入しているため、actor 欠落のような構造的に不正なボディがそのまま流れていました。 その観点では、enqueue 時点で検証し不正なジョブはキューに積まないのが一番良さそうです:
ただ inbox は意図的に軽量で、重い検証(署名・actor 解決)は processor 側に寄せていると理解しています。なので enqueue 時の検証は構造的・低コストなチェックに留めるのが良いかと思います getApId の null ガードは、getOneApId が空配列で getApId(undefined) を踏むケースもあるため、独立した汎用防御として残す想定です。 この方針で PR を更新してよければ対応しようかと思います。processor 側の早期ガードは defense-in-depth として残すか、enqueue 検証に一本化するかは判断をお願いできたらと...。 |
|
それで良さそうです。 |
|
@syuilo |
What
Inbox activities delivered without an
actorproperty crash the inbox queue job with an opaque error instead of being skipped:This PR:
getApId()againstnull/undefined, so it throws the intendedError('cannot determine id')instead of a rawTypeError(also fixes thedetemine→determinetypo).InboxProcessorService.process()withBull.UnrecoverableError, so they are skipped cleanly like other invalid inputs (and are not retried 128×).Fixes #17557. Related: #12720.
Why
InboxProcessorService.process()callsgetApId(activity.actor)in several places before any validation (theisDeleteshort-circuitgetApId(activity.actor) === getApId(activity.object), andgetAuthUserFromApId(getApId(activity.actor))). Whenactivity.actoris missing,getApId(undefined)evaluatesundefined.idand throws.On a small federated instance this produces on the order of ~100 failed jobs/day from malformed / actor-less deliveries, flooding error tracking and masking real problems.
Additional info
actor(it is used immediately for HTTP-Signature / authorship checks), so an activity without one was always going to fail — this just fails it cleanly and early instead of with a confusingTypeError.InboxProcessorServicehas no unit test suite (cf. fix: change bare activity.actor to getApId(activity.actor) in InboxPr… #17340).Checklist