Skip to content

Commit 033ad07

Browse files
committed
fix: address IDOR vulnerability in chat Supabase Edge Function
- Conducted a backend security audit and implemented a fix for an Insecure Direct Object Reference (IDOR) vulnerability in the chat function. - Added UUID format validation for `conversation_id` and ownership checks to ensure users can only modify their own conversations. - Verified changes with `deno check`, `npm run lint`, `npm run format`, and `npm run type-check`, all passing without errors.
1 parent 893b3f4 commit 033ad07

4 files changed

Lines changed: 102 additions & 0 deletions

File tree

AGENT.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ These rules govern the development of the Aion project.
99

1010
## Change Log
1111

12+
### 2026-05-21 (Australia/Sydney)
13+
**Raouf:**
14+
- **Scope:** Backend IDOR Security Fix
15+
- **Summary:** Performed a backend security audit and fixed an Insecure Direct Object Reference (IDOR) vulnerability in the chat Supabase Edge Function (`supabase/functions/chat/index.ts`). The function now validates the UUID format of incoming `conversation_id` and verifies that the authenticated user owns the conversation before updating it or inserting new messages, preventing users from altering others' conversations.
16+
- **Files Changed:**
17+
- [supabase/functions/chat/index.ts](file:///Users/raoof.r12/Desktop/Raouf/Aion/supabase/functions/chat/index.ts) - Added UUID format validation and ownership checks before conversation database updates and message inserts.
18+
- **Verification:** Ran `deno check supabase/functions/chat/index.ts`, `npm run lint`, `npm run format`, and `npm run type-check`, all completing with 0 errors.
19+
- **Follow-ups:** None.
20+
1221
### 2026-05-21 (Australia/Sydney)
1322
**Raouf:**
1423
- **Scope:** Syntax Fix & Supabase Resilience

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
## Change Log
88

9+
### 2026-05-21 (Australia/Sydney)
10+
**Raouf:**
11+
- **Scope:** Backend IDOR Security Fix
12+
- **Summary:** Performed a backend security audit and fixed an Insecure Direct Object Reference (IDOR) vulnerability in the chat Supabase Edge Function (`supabase/functions/chat/index.ts`). The function now validates the UUID format of incoming `conversation_id` and verifies that the authenticated user owns the conversation before updating it or inserting new messages, preventing users from altering others' conversations.
13+
- **Files Changed:**
14+
- [supabase/functions/chat/index.ts](file:///Users/raoof.r12/Desktop/Raouf/Aion/supabase/functions/chat/index.ts) - Added UUID format validation and ownership checks before conversation database updates and message inserts.
15+
- **Verification:** Ran `deno check supabase/functions/chat/index.ts`, `npm run lint`, `npm run format`, and `npm run type-check`, all completing with 0 errors.
16+
- **Follow-ups:** None.
17+
918
### 2026-05-21 (Australia/Sydney)
1019
**Raouf:**
1120
- **Scope:** Syntax Fix & Supabase Resilience

deno.lock

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

supabase/functions/chat/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY);
1010

1111
// --- Constants ---
1212
const MAX_MESSAGE_LENGTH = 500;
13+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1314

1415
// --- IP Extraction ---
1516
function getClientIp(req: Request): string {
@@ -239,6 +240,28 @@ async function persistMessages(
239240
if (error) throw new Error(`Create conversation error: ${error.message}`);
240241
convId = data.id;
241242
} else {
243+
// Validate UUID format to prevent DB type mismatch errors
244+
if (!UUID_REGEX.test(convId)) {
245+
throw new Error("Invalid conversation ID format");
246+
}
247+
248+
// Verify ownership to prevent IDOR (Insecure Direct Object Reference)
249+
const { data: conv, error: convError } = await supabase
250+
.from("conversations")
251+
.select("user_id")
252+
.eq("id", convId)
253+
.maybeSingle();
254+
255+
if (convError) {
256+
throw new Error(`Database error verifying conversation: ${convError.message}`);
257+
}
258+
if (!conv) {
259+
throw new Error("Conversation not found");
260+
}
261+
if (conv.user_id !== userId) {
262+
throw new Error("Unauthorized: Conversation does not belong to this user");
263+
}
264+
242265
await supabase
243266
.from("conversations")
244267
.update({ updated_at: new Date().toISOString() })

0 commit comments

Comments
 (0)