Fix CSRF in ajax.php enabling privilege escalation by requiring sessk… - #3389
Open
Patryk Mroczko (patmr7) wants to merge 1 commit into
Open
Fix CSRF in ajax.php enabling privilege escalation by requiring sessk…#3389Patryk Mroczko (patmr7) wants to merge 1 commit into
Patryk Mroczko (patmr7) wants to merge 1 commit into
Conversation
…ey validation local/o365/ajax.php required only require_login() and moodle/site:config, with no sesskey check on any of its state-changing modes. mode_checkteamsmoodlesetup in particular enables web services, the REST protocol, frame embedding, the bundled o365_webservices external service, and grants moodle/webservice:createtoken and webservice/rest:use to the default authenticated-user role - all unconditionally, on a simple GET request. A forged cross-site request against a logged-in administrator (e.g. via an <img> tag) silently expands these permissions to every authenticated user, regardless of whether the site uses Teams SSO at all. Add require_sesskey() to ajax.php, and append sesskey to the ajax.php URL built by the three admin_setting classes that call it (moodlesetup, verifysetup, serviceresource). These build their AJAX calls with plain jQuery rather than a sesskey-aware core JS module, so the sesskey is carried in the URL's query string instead, where jQuery's GET request serialization appends the remaining parameters.
There was a problem hiding this comment.
Pull request overview
This PR closes a CSRF vulnerability in local/o365/ajax.php by requiring Moodle sesskey validation for all AJAX modes, preventing state-changing requests from being triggered cross-site against a logged-in administrator.
Changes:
- Enforce
require_sesskey()inlocal/o365/ajax.phpbefore executing the requested mode. - Update the three admin setting UIs that call
ajax.phpto includesesskeyin the constructed AJAX URL query string.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| local/o365/classes/adminsetting/verifysetup.php | Adds sesskey to the AJAX endpoint URL used by the verify-setup UI. |
| local/o365/classes/adminsetting/serviceresource.php | Adds sesskey to the AJAX endpoint URL used by the service-resource UI. |
| local/o365/classes/adminsetting/moodlesetup.php | Adds sesskey to the AJAX endpoint URL used by the Moodle-setup UI. |
| local/o365/ajax.php | Requires sesskey validation for all AJAX modes to prevent CSRF-triggered state changes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…ey validation
local/o365/ajax.php required only require_login() and moodle/site:config, with no sesskey check on any of its state-changing modes. mode_checkteamsmoodlesetup in particular enables web services, the REST protocol, frame embedding, the bundled o365_webservices external service, and grants moodle/webservice:createtoken and webservice/rest:use to the default authenticated-user role - all unconditionally, on a simple GET request. A forged cross-site request against a logged-in administrator (e.g. via an
tag) silently expands these permissions to every authenticated user, regardless of whether the site uses Teams SSO at all.
Add require_sesskey() to ajax.php, and append sesskey to the ajax.php URL built by the three admin_setting classes that call it (moodlesetup, verifysetup, serviceresource). These build their AJAX calls with plain jQuery rather than a sesskey-aware core JS module, so the sesskey is carried in the URL's query string instead, where jQuery's GET request serialization appends the remaining parameters.