diff --git a/darkbazaar/src/main.py b/darkbazaar/src/main.py index 1053a4b..412155b 100755 --- a/darkbazaar/src/main.py +++ b/darkbazaar/src/main.py @@ -106,6 +106,12 @@ async def register_new_user( role: str = Form("seeker"), db: AsyncSession = Depends(get_db) ): + # SECURITY FIX: Detect HTTP Parameter Pollution + # Check if username, password, or role appears multiple times in form data + form_data = await request.form() + if len(form_data.getlist('username')) > 1 or len(form_data.getlist('password')) > 1 or len(form_data.getlist('role')) > 1: + return templates.TemplateResponse("register.html", {"request": request, "error": "Invalid request"}) + user_create = UserCreate(username=username, password=password, role=role) new_user = await create_user(db, user_create) if not new_user: @@ -120,6 +126,12 @@ async def login_user( password: str = Form(...), db: AsyncSession = Depends(get_db) ): + # SECURITY FIX: Detect HTTP Parameter Pollution + # Check if username or password appears multiple times in form data + form_data = await request.form() + if len(form_data.getlist('username')) > 1 or len(form_data.getlist('password')) > 1: + return templates.TemplateResponse("login.html", {"request": request, "error": "Invalid request"}) + user = await authenticate_user(db, username, password) if not user: return templates.TemplateResponse("login.html", {"request": request, "error": "User with this credentials doesn't exist"}) @@ -258,7 +270,9 @@ async def accept_ghostlink_request_endpoint( if not current_user.finder_insight_requests_as_ghostlink: return render_profile_template(request=request, user=current_user, error="Access denied: only \'ghostlink\' role can accept request.") - result = await accept_finder_insight_request(db, current_user, finder_username, username) + # SECURITY FIX: Ignore username parameter to prevent IDOR + # Only allow ghostlink to accept their own requests + result = await accept_finder_insight_request(db, current_user, finder_username, None) if isinstance(result, str): ghostlink_requests = await get_all_ghostlink_requests(db, current_user.username) return render_relationships_template(request=request, user=current_user, ghostlink_requests=ghostlink_requests, error=result) @@ -303,7 +317,9 @@ async def get_fulfilled_descriptions( if current_user.role != 'finder': raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied: only 'finder' role can view fulfilled descriptions.") - fulfilled_requests_orm = await get_all_fulfilled_seeker_requests(db, username) + # SECURITY FIX: Only allow finder to query their own data + # Ignore the username parameter and use authenticated user's username + fulfilled_requests_orm = await get_all_fulfilled_seeker_requests(db, current_user.username) return [FinderItemBase.model_validate(req) for req in fulfilled_requests_orm]