Fix BOLA (Broken Object Level Authorization) in Flask
Generated remediation sketch. GuardAPI the product only gates GET BOLA in CI.
BOLA (IDOR) is the apex predator of API vulnerabilities. It occurs when a backend fails to validate if the authenticated user has the right to access a specific resource ID. In Flask, developers often assume that because a user is logged in, they are authorized to access any object ID passed via URI parameters. This is a fatal assumption. To kill BOLA, you must enforce ownership at the database query level.
The Vulnerable Pattern
@app.route('/api/v1/orders/', methods=['GET'])
@login_required
def get_order(order_id):
# VULNERABLE: Only checks if user is logged in.
# An attacker can iterate 'order_id' to scrape all orders in the DB.
order = Order.query.filter_by(id=order_id).first()
if not order:
return jsonify({'error': 'Not found'}), 404
return jsonify(order.to_dict())
The Secure Implementation
The fix shifts the authorization logic from the application layer to the data access layer. By adding 'user_id=current_user.id' to the filter criteria, you ensure the database only returns records owned by the requester. Using 'first_or_404()' is a best practice; it prevents data leakage by returning the same error for a non-existent ID as it does for an unauthorized ID, effectively neutralizing resource enumeration attacks.
@app.route('/api/v1/orders/', methods=['GET'])
@login_required
def get_order(order_id):
# SECURE: Query is scoped to the authenticated user_id.
# If the order doesn't belong to the user, the query returns None.
order = Order.query.filter_by(id=order_id, user_id=current_user.id).first_or_404()
return jsonify(order.to_dict())
Prove it on the next pull request
This page is a generated code sketch, not a GuardAPI scan. After you scope the query by tenant, fail the GitHub job when tenant B can still GET tenant A's object. GET-only. Tokens stay in GitHub Secrets.
- uses: GuardAPI/ghost-api@v6
with:
api-key: ${{ secrets.GUARD_API_KEY }}
openapi-path: ./openapi.json
base-url: ${{ secrets.STAGING_API_URL }}
token-a: ${{ secrets.TOKEN_USER_A }}
token-b: ${{ secrets.TOKEN_USER_B }}
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