Spec: SDR 4.6 Security and Privacy — "The system shall protect user-uploaded academic content and personal schedule information" and "shall restrict access to each user's private notes, study materials, and calendar data." Also AGENTS.md gotcha #3.
The problem
app/api/chat/route.ts is eleven lines and has no session check. Anyone who can reach the deployment can POST to it and run inference on the project's Gemini key:
export async function POST(req: Request) {
const { messages } = await req.json();
return createAgentUIStreamResponse({ agent: baseAgent, uiMessages: messages });
}
Today the blast radius is quota abuse, since the agent has no tools. The moment AskHamiz gains tools over notes, classes, and the calendar, this becomes unauthenticated access to every user's data. It has to be fixed before that work lands.
Scope
- Add the standard guard to
/api/chat:
const session = await auth.api.getSession({ headers: await headers() });
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
- Audit every route under app/api/ for two things: a session guard, and a
userId filter on every DB read and write. Ownership must be enforced server-side, not inferred from a client-supplied id.
- Add per-user rate limiting on AI generation routes (chat, quiz generate, flashcards, note upload) so one account cannot exhaust the shared model quota.
- Confirm error responses follow AGENTS.md §5 — short user-facing string, real error to
console.error, never error.message from a catch.
Acceptance criteria
Spec: SDR 4.6 Security and Privacy — "The system shall protect user-uploaded academic content and personal schedule information" and "shall restrict access to each user's private notes, study materials, and calendar data." Also AGENTS.md gotcha #3.
The problem
app/api/chat/route.ts is eleven lines and has no session check. Anyone who can reach the deployment can POST to it and run inference on the project's Gemini key:
Today the blast radius is quota abuse, since the agent has no tools. The moment AskHamiz gains tools over notes, classes, and the calendar, this becomes unauthenticated access to every user's data. It has to be fixed before that work lands.
Scope
/api/chat:userIdfilter on every DB read and write. Ownership must be enforced server-side, not inferred from a client-supplied id.console.error, nevererror.messagefrom a catch.Acceptance criteria
/api/chatreturns 401 without a session