Link Search Menu Expand Document

Broken Authorization in Python

Play SecureFlag Play Python Labs on this vulnerability with SecureFlag!

Vulnerable example

The following snippet contains a generic administrative endpoint of a web application, written in Python, that allows for the deletion of the database when a specific URL is called.

# Route /admin/init
def admin_init():
    cursor.execute("DROP DATABASE analytics")
    return 'Database has been deleted to be reinstalled'

The /admin/init URI is available to everyone and should be protected by an authorization mechanism so that it can’t be abused by malicious actors.

Prevention

Apply the recommended authorization mechanisms depending on the web framework of choice.

Django

Django uses sessions that provide a request.user attribute, representing the current user. Authorization for different user roles can be easily checked with properties like User.is_superuser for users with admin privileges. This allows you to control access to different parts of the application based on their role.

def admin_init(request):
    if request.user.is_superuser:
        # Do something for superusers (users with admin privileges).
    else:
        # Do something for anonymous users (not logged in).

Flask

Flask-Session is an extension for Flask that adds support for server-side sessions to a web application.

from flask import Flask, session
from flask_session import Session

app = Flask(__name__)
app.config.from_object(__name__)
Session(app)

@app.route('/admin/init')
def admin_init():
    if not session.get('is_superuser'):
      abort(401)

FastAPI

FastAPI has built-in support for session management with web applications.

cookie_params = CookieParameters()

cookie = SessionCookie(
    cookie_name="cookie",
    identifier="general_verifier",
    auto_error=True,
    secret_key="DONOTUSE",
    cookie_params=cookie_params,
)

@app.post("/create_session/{name}")
async def create_session(name: str, response: Response):

    session = uuid4()
    data = SessionData(username=name)

    await backend.create(session, data)
    cookie.attach_to_response(response, session)

    return f"created session for {name}"

@app.get("/whoami", dependencies=[Depends(cookie)])
async def whoami(session_data: SessionData = Depends(verifier)):
    return session_data

References

MITRE - CWE 285 - Improper Authorization

OWASP Top 10 2021 - Broken Access Control

OWASP - Authorization Cheat Sheet