Skip to content

Security: enforce CSRF token validation on state-changing admin endpoints#8600

Merged
AngelFQC merged 1 commit into
masterfrom
security/auto-fix-GHSA-cxxm-wpv8-fwh9
Jun 18, 2026
Merged

Security: enforce CSRF token validation on state-changing admin endpoints#8600
AngelFQC merged 1 commit into
masterfrom
security/auto-fix-GHSA-cxxm-wpv8-fwh9

Conversation

@AngelFQC

Copy link
Copy Markdown
Member

Problem

Several platform-admin endpoints read $_POST and performed privileged state changes with no anti-CSRF token validation, accepting forged cross-site submissions backed only by the admin's session cookie:

File State-changing action
admin/course_export.php Export courses to CSV/XML/XLS
admin/course_import.php Import courses/users from CSV
admin/access_url_add_users_to_url.php Assign/unassign users to access URLs
admin/dashboard_add_courses_to_user.php Assign courses to HR managers
admin/add_sessions_to_promotion.php Subscribe sessions to promotions

Fix

Apply the standard Chamilo legacy CSRF idiom to each endpoint:

  • Guard the $_POST processing branch with Security::check_token('post'), rejecting via api_not_allowed(true) when the token is missing/invalid.
  • Emit a per-session token on the form when it is rendered:
    • FormValidator forms (course_export.php, course_import.php) → $form->addHidden('sec_token', Security::get_token()).
    • Hand-written forms (access_url_add_users_to_url.php, dashboard_add_courses_to_user.php, add_sessions_to_promotion.php) → Security::get_HTML_token(), which prints the hidden sec_token input and stores it in the session.

Token generation happens only on the render path, after the processing-time check_token(), so it never overwrites the token being verified.

Invariant now enforced

Each of these admin actions only runs when the request carries the per-session sec_token issued when the form was rendered; cross-site forged POSTs are rejected.

Notes for the reviewer

  • In access_url_add_users_to_url.php and add_sessions_to_promotion.php the forms also auto-submit for letter/search filtering. The token check covers those submissions too (the token is part of the form), and the genuinely state-changing branches (form_sent == 1) remain gated.

OWASP control

A01:2021 – Broken Access Control (CWE-352, Cross-Site Request Forgery).

Refs GHSA-cxxm-wpv8-fwh9

🤖 Generated with Claude Code

Refs GHSA-cxxm-wpv8-fwh9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AngelFQC AngelFQC force-pushed the security/auto-fix-GHSA-cxxm-wpv8-fwh9 branch from e0a5f2e to 2ab6607 Compare June 16, 2026 13:25
@AngelFQC AngelFQC merged commit b3f7a06 into master Jun 18, 2026
1 of 12 checks passed
@AngelFQC AngelFQC deleted the security/auto-fix-GHSA-cxxm-wpv8-fwh9 branch June 18, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant