From 324bf36b6d6a01cccaf7b78cf7ee65e577932434 Mon Sep 17 00:00:00 2001 From: 0XZAMAJ Date: Thu, 12 Jun 2025 10:53:29 +0100 Subject: [PATCH 1/4] Update README.md Signed-off-by: 0XZAMAJ --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a87a2723..7a74ca01 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,7 @@ ai, llm, decentralized-ai, generative-ai, asr, computer-vision, nlp, privacy, se ## ⭐ Show Your Support Give this repository a ⭐ and share it with your network to help grow the AIxBlock community. +a From a3c87e067a93b6bb8568e8985c827bddafdfbe17 Mon Sep 17 00:00:00 2001 From: 0XZAMAJ Date: Thu, 12 Jun 2025 11:55:40 +0100 Subject: [PATCH 2/4] Create idor-photo-deletion-report.md Signed-off-by: 0XZAMAJ --- idor-photo-deletion-report.md | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 idor-photo-deletion-report.md diff --git a/idor-photo-deletion-report.md b/idor-photo-deletion-report.md new file mode 100644 index 00000000..28398e3b --- /dev/null +++ b/idor-photo-deletion-report.md @@ -0,0 +1,66 @@ +# IDOR Vulnerability Report — Avatar Deletion Endpoint + +## Summary + +An Insecure Direct Object Reference (IDOR) vulnerability was discovered in the `/api/users/:userId/avatar` endpoint. This allows any authenticated user to delete another user’s profile picture by changing the `userId` in the request URL. + +--- + +## Steps to Reproduce + +1. Create two user accounts: **Account A** and **Account B**. +2. Upload different profile pictures for each account. +3. Log in as **Account A**. +4. Intercept and send the following request: + +DELETE /api/users/{userId}/avatar HTTP/2 +Host: app.aixblock.io + + +Replace `{userId}` with the ID of **Account B**. + +Result: Account B’s profile photo is deleted by Account A without authorization errors. + +--- + +## Expected Behavior + +The backend should enforce proper authorization checks so that: + +- Users can only delete **their own photo** +- Attempting to delete another user’s photo should result in a **403 Forbidden** response. + +--- + +## Security Impact + +This issue allows any authenticated user to perform unauthorized actions on other users’ data. It violates user trust and can cause: + +- Visual identity disruption +- Potential abuse in a multi-user environment + +--- + +## Suggested Fix + +- Add an authorization check to the avatar deletion endpoint that verifies: + - `request.user.id === params.userId` +- Reject the request with appropriate HTTP status (e.g., 403) if the IDs do not match. + +--- + +## Environment + +- Tested using: Chrome browser + Burp Suite +- Endpoint affected: `DELETE /api/users/:userId/avatar` +- Backend version possibly affected: `aixblock-core v0.0.8` + +--- + +## Reported by + +@0XZAMAJ + +--- + +Let me know if additional details or logs are needed. I’m happy to help clarify or test more if needed. From 706f70b9c2a564ee6fc6f98b4e929c5256a00533 Mon Sep 17 00:00:00 2001 From: 0XZAMAJ Date: Sat, 21 Jun 2025 09:57:12 +0100 Subject: [PATCH 3/4] Create fix-issue-24.md Signed-off-by: 0XZAMAJ --- fix-issue-24.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 fix-issue-24.md diff --git a/fix-issue-24.md b/fix-issue-24.md new file mode 100644 index 00000000..9b6e978f --- /dev/null +++ b/fix-issue-24.md @@ -0,0 +1,28 @@ +# Fix Proposal for Issue #24 — IDOR on /api/users/:id/avatar + +## Summary + +This document proposes a fix for the Insecure Direct Object Reference (IDOR) vulnerability reported in Issue #24. The issue allows any authenticated user to delete the avatar of another user by modifying the `userId` in the URL. + +--- + +## Root Cause + +The endpoint `/api/users/:id/` lacks an ownership check between the `userId` in the URL and the authenticated user in the session/token. The backend trusts the user-provided `:id` instead of validating it. + +--- + +## Proposed Fix + +Introduce a centralized ownership validation helper that can be reused across sensitive user endpoints. + +### 🔧 Helper Function (utils/validate-ownership.ts) + +```ts +import { ForbiddenException } from '@nestjs/common'; + +export function validateOwnership(requestUserId: number, paramUserId: number) { + if (requestUserId !== paramUserId) { + throw new ForbiddenException('Unauthorized: You do not have permission!'); + } +} From 41be95857dcb1872220f916d5be58a7e38f6f8de Mon Sep 17 00:00:00 2001 From: 0XZAMAJ Date: Thu, 11 Sep 2025 19:45:26 +0100 Subject: [PATCH 4/4] Update .env.example Signed-off-by: 0XZAMAJ --- .env.example | 80 +++++++--------------------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) diff --git a/.env.example b/.env.example index 0fbf1a48..7f0c383f 100644 --- a/.env.example +++ b/.env.example @@ -1,74 +1,14 @@ -ENVIRONMENT=dev # stg, prod -AXB_NAME='aixblock-platform' -AIXBLOCK_IMAGE_VERSION=7.0.8_dev -AIXBLOCK_IMAGE_NAME=aixblock/platform -AXB_HOST=https://app.aixblock.io/ -BASE_BACKEND_URL=https://app.aixblock.io/ -AXB_PUBLIC_PORT=8080 -AXB_PUBLIC_SSL_PORT=8443 -AXB_DATA=/aixblock/data -AXB_LOG_LEVEL=ERROR -CRAWL_URL=https://crawling.aixblock.io/ -POSTGRES_NAME=platform_v2 -POSTGRES_USER=postgres -POSTGRES_PASSWORD=@9^xwWA +# Database settings +POSTGRES_USER=yourusername +POSTGRES_PASSWORD=yourpassword +POSTGRES_HOST=localhost POSTGRES_PORT=5432 -POSTGRES_HOST=127.0.0.1 -#ADMIN LOGIN -ADMIN_EMAIL=admin@test.com -ADMIN_USERNAME=admin -ADMIN_PASSWORD=admin123 - -LETSENCRYPT_PATH=/etc/letsencrypt - -#SESSION_REDIS -SESSION_REDIS_HOST='localhost' +# Redis settings +SESSION_REDIS_HOST=localhost SESSION_REDIS_PORT=6379 -SESSION_REDIS_DB=0 -SESSION_REDIS_PASSWORD='' -SESSION_REDIS_USER='' -SESSION_REDIS_PREFIX='session' -SESSION_REDIS_SOCKET_TIMEOUT=1800 -SESSION_REDIS_TLS=false -BASE_DIR=/Users/macbookpro16/platform-v2/ -# -SHARED_SECRET_KEY='42d8236921664c1fb7097455e9e9c6ea' -#GOOGLE_OAUTH2 -GOOGLE_OAUTH2_CLIENT_ID='' -GOOGLE_OAUTH2_CLIENT_SECRET='' -GOOGLE_OAUTH2_PROJECT_ID='' -#OAUTH SERVER -OAUTH_CLIENT_ID='cII7nNypNovzLYIZPRTv6DeuljC4nqWju4NxZakF' -OAUTH_CLIENT_SECRET='RNAk3Fo9bXrwJnC1CJwnjtJGIkUNb9syKDbBPlhPZw4hRsocayj380pX6txcCvALtqgca9AXRBKBYO9yvQ8q231t5RBG9b83UbOdsHEQDNpqFCTEJ3WA4sYJ2K96mWCu' -OAUTH_TOKEN_URL='https://app.aixblock.io/o/token/' -OAUTH_AUTHORIZE_URL='https://app.aixblock.io/o/authorize' -OAUTH_API_BASE_URL='https://app.aixblock.io/' -OAUTH_REDIRECT_URL='https://app.aixblock.io/oauth/login/callback' -# JUPYTER_NOTEBOOK. URL must always ended withs / -NOTEBOOK_URL=https://jupyter.aixblock.io -NOTEBOOK_TOKEN=bac99e2a1b4446a7bced64484eea7db8 -MASTER_NODE='' -MASTER_TOKEN='' - -# CDN -ASSETS_CDN=https://aixblock-staging.b-cdn.net - -CENTRIFUGE_SECRET="" -CENTRIFUGE_URL="" - -# secret key for password minio -MINIO_API_IP="" -MINIO_API_URL="" -MINIO_USER="" -MINIO_PASSWORD="" - -# Added 0.0.4 -SECRET_KEY= +SESSION_REDIS_PASSWORD=yourpassword -# Workflow -NPM_TOKEN= -WORKFLOW_ENCRYPTION_KEY=698bd045fbf8901a4f4023470605c0f5 -WORKFLOW_JWT_SECRET=eee6c47e15faea067088c8e7318fb6adf81734dc8df3d96f9fed05e610928ba0 -WORKFLOW_DEV_BLOCKS=aixblock,data-mapper,gmail,google-sheets,schedule,store,webhook -WORKFLOW_ENDPOINT=http://127.0.0.1:4200 +# OAuth settings +OAUTH_CLIENT_ID=yourclientid +OAUTH_CLIENT_SECRET=yourclientsecret