Description
Improper authorization occurs when an application does not verify a user’s permissions or reject requests that lack the required access. Unauthorized users may then reach restricted resources or operations.
Potential impact
- Privilege escalation: Unauthorized users may gain administrative capabilities.
- Data exposure: Sensitive data may be disclosed to users who lack access.
- Service disruption: Unauthorized operations on system resources may interrupt the service.
Remediation
- Check permissions for every sensitive operation and resource access.
- Reject unauthorized requests before performing the operation and return an appropriate HTTP error status. Changing the error message alone does not enforce access control.
- Use the authentication and authorization features available in Django, Flask or FastAPI.
Examples
These excerpts omit authentication setup, session management and user lookup. Flask-Login requires a verified user loader and login configuration; is_admin must come from trusted permission data, not client input.
Django
Before
python
# Unsafe Django code
from django.http import HttpResponse
def view_sensitive_data(request):
if request.user.username != 'admin':
return HttpResponse("Not authorized")
# Process sensitive data
return HttpResponse("Sensitive data")
After
python
# Safe Django code
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required, user_passes_test
@login_required
@user_passes_test(lambda u: u.is_superuser)
def view_sensitive_data(request):
# Process sensitive data
return HttpResponse("Sensitive data")
Explanation:
- Before: The username is treated as an administrative permission. Do not assume this string comparison safely enforces user registration, renaming and authorization policies.
- After: Django’s
login_requiredanduser_passes_testdecorators restrict access to authenticated users who pass the superuser check.
Flask
Before
python
# Unsafe Flask code
from flask import Flask, request
app = Flask(__name__)
@app.route('/sensitive')
def view_sensitive_data():
if request.args.get('user') != 'admin':
return "Not authorized"
# Process sensitive data
return "Sensitive data"
After
python
# Safe Flask code
from flask import Flask, request, abort
from flask_login import login_required, current_user
app = Flask(__name__)
@app.route('/sensitive')
@login_required
def view_sensitive_data():
if not current_user.is_admin:
return abort(403)
# Process sensitive data
return "Sensitive data"
Explanation:
- Before: The client can choose the
userquery parameter, so it cannot establish administrative authority. - After: Flask-Login supplies the authenticated
current_user; the handler rejects users without the required permission.
FastAPI
Before
python
# Unsafe FastAPI code
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.get("/sensitive")
async def view_sensitive_data(request: Request):
if request.query_params.get('user') != 'admin':
return {"detail": "Not authorized"}
# Process sensitive data
return {"detail": "Sensitive data"}
After
python
# Safe FastAPI code
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class User(BaseModel):
username: str
is_admin: bool
def get_current_user(token: str = Depends(oauth2_scheme)):
# Reject access until real token verification and user lookup are implemented.
raise HTTPException(status_code=401, detail="Token verification is not configured")
@app.get("/sensitive")
async def view_sensitive_data(current_user: User = Depends(get_current_user)):
if not current_user.is_admin:
raise HTTPException(status_code=403, detail="Not authorized")
# Process sensitive data
return {"detail": "Sensitive data"}
Explanation:
- Before: A client-supplied username in the URL is trusted for access control.
- After:
OAuth2PasswordBearerextracts a bearer token but does not validate it. This excerpt rejects access until verification is implemented. Implementget_current_userto verify the token and retrieve permissions from a trusted user store before returning aUser.