-
Notifications
You must be signed in to change notification settings - Fork 239
IDOR on deep-research task results — no ownership check #39
Description
- Context: Cloud / Both
- Category: Vulnerability (Insecure Direct Object Reference)
- Severity: High
Evidence
The task-status route authenticates the caller but never verifies that the taskId belongs to the authenticated session:
// app/api/deepresearch/[taskId]/route.ts
export async function GET(request, { params }) {
const { taskId } = await params;
const accessToken = searchParams.get("accessToken");
const selfHosted = isSelfHostedMode();
if (!selfHosted && !accessToken) {
return NextResponse.json({ error: "Authentication required" }, { status: 401 });
}
// ✅ Checks: is the user authenticated?
// ❌ Missing: does this taskId belong to this user/session?
const statusData = await getStatusViaProxy(taskId, accessToken);
// statusData contains: generated content, sources, pdfUrl, deliverables
}The response includes the full generated intelligence dossier, source list, PDF/PPTX download URLs, and CSV export data.
Scenario: User A starts a deep-research task; their taskId leaks via a server log, an APM trace, a Referer header (because taskId appears in the polling URL), or a shared log aggregator. Any other authenticated user who learns the taskId can retrieve the complete dossier without authorization.
If Valyu's backend enforces ownership on its side, this risk is partially mitigated — but the application provides no defense-in-depth layer, and any self-hosted-mode request (no auth required) bypasses even that.
Impact: Unauthorized read access to potentially sensitive intelligence dossiers generated by other users.
Affected files: app/api/deepresearch/[taskId]/route.ts, components/search/entity-search.tsx