Security Report
Security audit identified 3 HIGH severity vulnerabilities in daloRADIUS.
1. SQL Injection in Operator Creation (HIGH)
File: app/operators/config-operators-new.php:88-96
Pattern: 1-of-N inconsistency (edit escapes, create does not)
When creating a new operator, the INSERT query uses POST parameters directly in sprintf() without $dbSocket->escapeSimple(). All 14 fields (username, password, firstname, lastname, title, department, company, phone1, phone2, email1, email2, messenger1, messenger2, notes) are unescaped.
The operator edit page (config-operators-edit.php:99-104) properly escapes all the same fields. The SELECT query on line 72 of the create page also uses escapeSimple(), but the INSERT does not.
Impact: An authenticated operator with create-operator ACL can inject SQL to read/modify arbitrary database records.
Fix: Apply $dbSocket->escapeSimple() to all interpolated values in the INSERT, matching the edit page pattern.
2. AJAX Endpoints Missing ACL Authorization Check (HIGH)
Files: All files in app/operators/library/ajax/ (6 files)
All AJAX endpoint files include checklogin.php (authentication) but NONE include check_operator_perm.php (ACL authorization):
| File |
Risk |
user_actions.php |
Enable/disable users, refill sessions, send credential emails |
user_info.php |
View user bandwidth |
json_api.php |
Search all usernames |
attributes.php |
Manage RADIUS dictionary attributes |
hotspot_info.php |
View hotspot info |
vendor_attribute_info.php |
View vendor attribute data |
Impact: Any authenticated operator, regardless of ACL permissions, can enable/disable RADIUS users, refill sessions, send credential emails with plaintext passwords, and enumerate all usernames.
Fix: Add include('check_operator_perm.php') with appropriate permission names to each AJAX file.
3. Plaintext Operator Password Storage (HIGH)
Files: app/operators/dologin.php:64-65, config-operators-new.php:89, config-operators-edit.php:95
Operator passwords are stored in plaintext and compared via direct string matching in SQL. No password_hash()/password_verify() anywhere in the operator auth flow.
Impact: Database backups (downloadable via the backup UI) expose all operator passwords in cleartext.
Fix: Use password_hash(PASSWORD_DEFAULT) for storage and password_verify() for login.
Positive Notes
The platform has good security practices overall: consistent checklogin.php includes on all 120+ pages, CSRF protection on all forms, proper escapeshellarg() for shell commands, and escapeSimple() on the vast majority of SQL queries.
Reported by Lighthouse Security Research (lighthouse1212.com)
Security Report
Security audit identified 3 HIGH severity vulnerabilities in daloRADIUS.
1. SQL Injection in Operator Creation (HIGH)
File:
app/operators/config-operators-new.php:88-96Pattern: 1-of-N inconsistency (edit escapes, create does not)
When creating a new operator, the INSERT query uses POST parameters directly in
sprintf()without$dbSocket->escapeSimple(). All 14 fields (username, password, firstname, lastname, title, department, company, phone1, phone2, email1, email2, messenger1, messenger2, notes) are unescaped.The operator edit page (
config-operators-edit.php:99-104) properly escapes all the same fields. The SELECT query on line 72 of the create page also usesescapeSimple(), but the INSERT does not.Impact: An authenticated operator with create-operator ACL can inject SQL to read/modify arbitrary database records.
Fix: Apply
$dbSocket->escapeSimple()to all interpolated values in the INSERT, matching the edit page pattern.2. AJAX Endpoints Missing ACL Authorization Check (HIGH)
Files: All files in
app/operators/library/ajax/(6 files)All AJAX endpoint files include
checklogin.php(authentication) but NONE includecheck_operator_perm.php(ACL authorization):user_actions.phpuser_info.phpjson_api.phpattributes.phphotspot_info.phpvendor_attribute_info.phpImpact: Any authenticated operator, regardless of ACL permissions, can enable/disable RADIUS users, refill sessions, send credential emails with plaintext passwords, and enumerate all usernames.
Fix: Add
include('check_operator_perm.php')with appropriate permission names to each AJAX file.3. Plaintext Operator Password Storage (HIGH)
Files:
app/operators/dologin.php:64-65,config-operators-new.php:89,config-operators-edit.php:95Operator passwords are stored in plaintext and compared via direct string matching in SQL. No
password_hash()/password_verify()anywhere in the operator auth flow.Impact: Database backups (downloadable via the backup UI) expose all operator passwords in cleartext.
Fix: Use
password_hash(PASSWORD_DEFAULT)for storage andpassword_verify()for login.Positive Notes
The platform has good security practices overall: consistent
checklogin.phpincludes on all 120+ pages, CSRF protection on all forms, properescapeshellarg()for shell commands, andescapeSimple()on the vast majority of SQL queries.Reported by Lighthouse Security Research (lighthouse1212.com)