Skip to content

fix: Openai thread IDOR#10806

Merged
mergify[bot] merged 6 commits intomasterfrom
fix/openai-thread-idor
Feb 26, 2026
Merged

fix: Openai thread IDOR#10806
mergify[bot] merged 6 commits intomasterfrom
fix/openai-thread-idor

Conversation

@ryotaro-nagahara
Copy link

@ryotaro-nagahara ryotaro-nagahara commented Feb 20, 2026

Task

https://redmine.weseek.co.jp/issues/178646

原因

OpenAI関連APIにおいて、threadId や threadRelationId の所有者検証が欠落していた。

具体的には、get-threadsget-messagespost-messagedelete-threadedit の各エンドポイントでThreadRelation を取得する際、aiAssistantIdthreadId のみで検索しており userId による絞り込みを行っていなかった。
これにより、共有AIアシスタントの aiAssistantId さえ知っていれば、他ユーザーのスレッド一覧の取得、メッセージの閲覧・投稿・編集、スレッドの削除が可能な状態となっていた。

修正案

全5エンドポイントのルートハンドラで、ThreadRelationModel のクエリ条件に userId: user._id を追加し、リクエスト者自身のスレッドのみ操作可能にした。
所有権チェックはすべてルートハンドラ内で ThreadRelationModel のクエリ条件に userId を含める方式に統一した。


const threadRelation = await ThreadRelationModel.findOne({
threadId: { $eq: threadId },
userId: user._id,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

既存の findOne クエリに userId 条件を追加した

if (threadRelation == null) {
return res.apiv3Err(new ErrorV3('Thread not found'), 404);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThreadRelationModel.findOne による userId 付きクエリで所有権を確認してからメッセージ取得するよう変更した

const threadRelation = await ThreadRelationModel.findOne({
threadId,
userId: user._id,
});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThreadRelationModel.findOne による userId 付きクエリで所有権を確認してからメッセージ取得するよう変更した

if (threadRelation == null) {
return res.apiv3Err(new ErrorV3('Thread not found'), 404);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThreadRelationModel.findOne による userId 付きクエリで所有権を確認してからサービスメソッドを呼び出すよう変更

aiAssistant: aiAssistantId,
userId: user._id,
type: ThreadType.KNOWLEDGE,
}).sort({ updatedAt: -1 });
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThreadRelationModel.find のクエリ条件に userId を追加した

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type: ThreadType.KNOWLEDGE はなんで必要なんだっけ?

Copy link
Author

@ryotaro-nagahara ryotaro-nagahara Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

他のファイル(get-messages・post-message・edit)は元々ルートハンドラ内で ThreadRelationModel.findOne を使っていたため、既存のクエリに userId を追加するだけで済んだのに対し、
get-threads は元々サービスメソッド getThreadsByAiAssistantId 経由でDBアクセスしていたため、ThreadRelationModel.find への置き換えが必要になったという認識です。

その際、サービスメソッドのデフォルト引数で指定されていた type: ThreadType.KNOWLEDGE の条件も引き継ぐという形になりました。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getThreadsByAiAssistantId の方を改修してほしいです

@ryotaro-nagahara ryotaro-nagahara changed the title fix: Openai thread IDOR (vulnerability) fix: Openai thread IDOR Feb 20, 2026
aiAssistant: aiAssistantId,
userId: user._id,
type: ThreadType.KNOWLEDGE,
}).sort({ updatedAt: -1 });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type: ThreadType.KNOWLEDGE はなんで必要なんだっけ?

aiAssistant: aiAssistantId,
userId: user._id,
type: ThreadType.KNOWLEDGE,
}).sort({ updatedAt: -1 });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getThreadsByAiAssistantId の方を改修してほしいです

Copy link
Author

@ryotaro-nagahara ryotaro-nagahara Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getThreadsByAiAssistantIduserId: string を追加すると、274行目のメソッド updateThreads がこのメソッドを userId なしで呼んでいるためコンパイルエラーになりました。
そのため、userId?: stringとし、オプショナルにすることで、ルートハンドラからは userId 付きでユーザー自身のスレッドのみを取得し、内部の updateThreads からは従来通り userId なしで全スレッドを対象に処理できるようにしました。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId を渡して所有者のスレッドのみ取得するよう変更

): Promise<ThreadRelationDocument[]> {
const threadRelations = await ThreadRelationModel.find({
aiAssistant: aiAssistantId,
...(userId != null && { userId }),
Copy link
Member

@miya miya Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっとトリッキーな気がする
こんな感じに書けないかな?

const query = {
  aiAssistant: aiAssistantId,
  type,
};

if (userId != null) {
  query.userId = userId;
}

const threadRelations = await ThreadRelationModel
  .find(query)
  .sort({ updatedAt: -1 });

@yuki-takei yuki-takei requested a review from miya February 26, 2026 07:32
@yuki-takei
Copy link
Contributor

@mergify queue

@mergify
Copy link
Contributor

mergify bot commented Feb 26, 2026

Merge Queue Status

Rule: default


This pull request spent 12 minutes 57 seconds in the queue, including 12 minutes 46 seconds running CI.

Required conditions to merge
  • -check-failure ~= ci-app-
  • -check-failure ~= ci-slackbot-
  • -check-failure ~= test-prod-node20 /
  • check-success = test-prod-node20 / build-prod
  • check-success ~= ci-app-launch-dev
  • check-success ~= ci-app-lint
  • check-success ~= ci-app-test
  • check-success ~= test-prod-node20 / launch-prod
  • check-success ~= test-prod-node20 / run-playwright

@mergify mergify bot added the queued label Feb 26, 2026
mergify bot added a commit that referenced this pull request Feb 26, 2026
@mergify mergify bot merged commit b91bd9b into master Feb 26, 2026
27 checks passed
@mergify mergify bot deleted the fix/openai-thread-idor branch February 26, 2026 07:46
@mergify mergify bot removed the queued label Feb 26, 2026
@github-actions github-actions bot mentioned this pull request Feb 26, 2026
@github-actions github-actions bot mentioned this pull request Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants