Skip to content

OWASP Top 10 (2021) Detailed

Broken access control is the most critical web application security risk. It occurs when users can Act outside their intended permissions.

# VULNERABLE: Any user can access any order by changing the ID
@app.route("/api/orders/<order_id>')
def get_order(order_id):
order = db.query("SELECT * FROM orders WHERE id = %s", (order_id,))
return jsonify(order)
# SAFE: Verify the user owns the resource
@app.route('/api/orders/<order_id>')
@require_auth
def get_order(order_id):
order = db.query(
"SELECT * FROM orders WHERE id = %s AND customer_id = %s",
(order_id, current_user.id)
)
if not order:
return jsonify({"error": "Not found"}), 404
return jsonify(order)
# VULNERABLE: Role from user input, not from session
@app.route('/api/admin/users')
def admin_panel():
role = request.args.get('role', 'user') # attacker sets ?role=admin
if role == 'admin':
return jsonify(admin_data)
return jsonify(user_data)
# SAFE: Role from authenticated session
@app.route('/api/admin/users')
@require_role('admin')
def admin_panel():
return jsonify(admin_data)
# VULNERABLE: attacker reads arbitrary files
@app.route('/download')
def download():
filename = request.args.get('file')
return send_file(f'/var/data/{filename}')
# ?file=../../etc/passwd
# SAFE: validate and sanitize the path
import os
@app.route('/download')
def download():
filename = request.args.get('file')
base_dir = '/var/data/uploads'
filepath = os.path.realpath(os.path.join(base_dir, filename))
if not filepath.startswith(os.path.realpath(base_dir)):
return jsonify({"error": "Invalid path"}), 400
if not os.path.isfile(filepath):
return jsonify({"error": "Not found"}), 404
return send_file(filepath)
MethodTool / Approach
Automated scanningOWASP ZAP, Burp Suite Pro
Manual testingModify IDs, roles, paths in requests
Code reviewCheck for missing authorization
Access control matrixDocument and test all routes