Broken Authentication in Python
Vulnerable example
The following snippet contains a Flask web application, written in Python, which has an administrative functionality to delete the database when a specific URL is called.
@app.route('/admin/init', methods=['POST'])
def reinitialize():
cursor.execute("DROP DATABASE analytics")
return 'Database has been dropped'
The /admin/init
URI is available to everyone and should be protected by an authentication mechanism so that it can’t be abused by malicious actors.
Prevention
Apply the recommended authentication and authorization mechanisms depending on the web framework of choice.
Django
Django uses sessions that provide a request.user
attribute which represents the current user. If the current user has not logged in, the attribute is set to AnonymousUser
object. The authentication status can be easily checked with User.is_authenticated
.
def admin_init(request):
if request.user.is_authenticated:
# Do something for authenticated users.
else:
# Do something for anonymous users.
Permission can be assigned to users and groups, and it can be validated with User.has_perm()
.
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
def admin_init(request, user_id):
user = get_object_or_404(User, pk=user_id)
user.has_perm('myapp.change_database')
...
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('logged_user'):
abort(401)
References
CWE - CWE-287: Improper Authentication
OWASP - A07:2021 - Identification and Authentication Failures