GuardAPI
Automated Security Protocol

How to fix BOLA (Broken Object Level Authorization)
in Dart Frog

Executive Summary

BOLA (Broken Object Level Authorization) is the apex predator of API vulnerabilities. In the context of Dart Frog, it occurs when your routes trust the resource ID provided in the path without verifying that the authenticated user has the right to access it. This allows an attacker to iterate through IDs and exfiltrate or modify data belonging to other users. To kill BOLA, you must enforce authorization at the data-access layer by cross-referencing the resource owner against the session context.

The Vulnerable Pattern

VULNERABLE CODE
import 'package:dart_frog/dart_frog.dart';
import '../database_client.dart';

// routes/users/[id]/profile.dart Future onRequest(RequestContext context, String id) async { // VULNERABLE: The ‘id’ is taken directly from the URL. // An attacker can change /users/123/profile to /users/124/profile // and access anyone’s data because there is no ownership check. final profile = await context.read().findProfile(id);

if (profile == null) { return Response(statusCode: 404); }

return Response.json(body: profile.toJson()); }

The Secure Implementation

The fix involves three critical steps. First, implement an authentication middleware that injects the current 'User' object into the 'RequestContext'. Second, when a request hits a dynamic route (like [id]), fetch the requested object from your data store. Third, perform an 'Authorization Check' by comparing the 'owner_id' of the fetched object against the 'id' of the authenticated user. If they don't match, return a 403 Forbidden. For maximum stealth against ID enumeration, you may choose to return a 404 Not Found instead.

SECURE CODE
import 'package:dart_frog/dart_frog.dart';
import '../database_client.dart';
import '../models/user.dart';

// routes/users/[id]/profile.dart Future onRequest(RequestContext context, String id) async { // 1. Retrieve the authenticated user from the RequestContext (populated by middleware) final authenticatedUser = context.read();

// 2. Fetch the resource final profile = await context.read().findProfile(id);

if (profile == null) { return Response(statusCode: 404); }

// 3. SECURE: Explicitly verify that the authenticated user owns the resource // Never rely on the ID provided in the URL alone. if (profile.userId != authenticatedUser.id) { return Response(statusCode: 403, body: ‘Unauthorized access to resource.’); }

return Response.json(body: profile.toJson()); }

About this page

Framework notes in /guides are generated sketches kept for URL stability. They are not human pentest reports and they are not GuardAPI scan output. The product is a GET-only BOLA merge gate. Maintained by GuardAPI. Questions: support@guard-api.com