Skip to main content

API1:2023 Broken Object Level Authorization

Endpoints accept a caller-controlled object identifier (path or query parameter) and read or write the named object without confirming the caller is allowed to touch it. The most common production breach class: a /users/123/orders/456 endpoint that returns order 456 regardless of who owns it.

What Vulkro detects

Vulkro flags handlers whose route declares an :id-style path or query parameter and whose body reads or writes the named object without a visible ownership check (no .where(user=current_user), no role assertion, no scoping middleware on the route).

Non-compliant code (examples)

Django REST — owner check missing

@api_view(['GET'])
def get_order(request, order_id):
order = Order.objects.get(pk=order_id)
return Response(OrderSerializer(order).data) # any caller sees any order

Compliant code (examples)

Django REST — owner predicate on the lookup

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_order(request, order_id):
order = Order.objects.get(pk=order_id, customer=request.user)
return Response(OrderSerializer(order).data)

See also

  • Confidence model - what High, Medium, and Low mean for findings in this category.
  • Safety - what Vulkro does and does not access on your machine.

References


This page is generated by vulkro rules export <out-dir> from the catalog in src/rule_docs.rs. Edits made by hand are overwritten on the next regeneration.