🔐 This Code Will Betray You: The Hidden Flaw in Your Admin Panel
The Hidden Flaw in Your Admin Panel Imagine you've built a web application. Login system works, passwords are hashed, everything looks solid. You feel confident. Then someone simply types this URL:GET /admin/dashboard and walks right in. No attack tools, no exploit. Just a URL .This is Broken Access Control — ranked #1 on OWASP's list of the most critical web security risks. And it almost always comes from the simplest mistake.
Where Is the Flaw?
Take a look at this Flask code:_
__@app.route("/admin/dashboard")
def admin_dashboard():
user_ id = session .get("user _id")
if not user _id:
return jsonify ({"error": "Please log in"}), 401
user = users. get(user_ id)
return jsonify({"data": f" Welcome, {user['name']}! This is the admin panel."})
The code asks only one question: "Is this person logged in?"
What it never asks: "Does this person actually have permission to be here?"
So a regular user logs in, navigates to the URL, and gets this:
{"data": "Welcome, Ali! This is the admin panel."}
Ali is a regular user — but he's inside the admin panel. The code works perfectly. That's exactly why this bug goes unnoticed for so long.
**
The Fix**
def admin_ required(f):
@wraps(f)
def decorated(*args, ** kwargs):
user_ id = session .get("user _id")
if not user_ id:
return jsonify({"error": "Please log in"}), 401
user = users. get(user_ id)
if not user or user["role"] != "admin":
return jsonify({"error": "Access denied"}), 403
return f(*args, **kwargs)
return decorated
@app.route("/admin/dashboard")
@admin_required
def admin_ dashboard():
@admin_ required — one line, full protection.
Write it once, attach it to every protected route. If you forget — it returns 403, not your admin data.
The Lesson
Authentication and authorization are not the same thing.
Authentication asks: "Who are you?"
Authorization asks: "What are you allowed to do?"
Locking the front door while leaving every room inside wide open is only half a security model.
And hiding the URL doesn't help either. /admin/secret-panel-xyz is not protection — it's just obscurity. Anyone who finds it gets in.
Every time you write an endpoint, ask yourself:
"Am I checking that the user is logged in — or that they're allowed to be here?"
One small line of code. One very large difference.
This article is part of a series on Broken Access Control. Next up: IDOR — how attackers access anyone's data using nothing but an ID.
🏷️ Dev.to Tags
#python #security #webdev #flask #beginners
`
Top comments (0)