MDL-65075 tool_mobile: Allow auto-login keys only for requests from Moodle apps

This change enhances security and avoid any kind of XSS attack.
This commit is contained in:
Juan Leyva 2019-03-21 15:39:21 +01:00
parent 9d4f4f0051
commit 102e0828fd
6 changed files with 49 additions and 1 deletions

View File

@ -297,6 +297,11 @@ class api {
throw new moodle_exception('enablewsdescription', 'webservice');
}
// Only requests from the Moodle mobile or desktop app. This enhances security to avoid any type of XSS attack.
if (!\core_useragent::is_moodle_app()) {
throw new moodle_exception('apprequired', 'tool_mobile');
}
if (!is_https()) {
throw new moodle_exception('httpsrequired', 'tool_mobile');
}

View File

@ -262,6 +262,8 @@ class external extends external_api {
/**
* Creates an auto-login key for the current user. Is created only in https sites and is restricted by time and ip address.
*
* Please note that it only works if the request comes from the Moodle mobile or desktop app.
*
* @param string $privatetoken the user private token for validating the request
* @return array with the settings and warnings
* @since Moodle 3.2

View File

@ -57,7 +57,8 @@ $functions = array(
'classname' => 'tool_mobile\external',
'methodname' => 'get_autologin_key',
'description' => 'Creates an auto-login key for the current user.
Is created only in https sites and is restricted by time and ip address.',
Is created only in https sites and is restricted by time, ip address and only works if the request
comes from the Moodle mobile or desktop app.',
'type' => 'write',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),

View File

@ -27,6 +27,7 @@ $string['androidappid'] = 'Android app\'s unique identifier';
$string['androidappid_desc'] = 'This setting may be left as default unless you have a custom Android app.';
$string['apppolicy'] = 'App policy URL';
$string['apppolicy_help'] = 'The URL of a policy for app users which is listed on the About page in the app. If the field is left empty, the site policy URL will be used instead.';
$string['apprequired'] = 'This functionality is only available when accessed via the Moodle mobile or desktop app.';
$string['autologinkeygenerationlockout'] = 'Auto-login key generation is blocked. You need to wait 6 minutes between requests.';
$string['autologinnotallowedtoadmins'] = 'Auto-login is not allowed for site admins.';
$string['cachedef_plugininfo'] = 'This stores the list of plugins with mobile addons';

View File

@ -213,6 +213,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
// Enable requeriments.
$_GET['wstoken'] = $token->token; // Mock parameters.
// Fake the app.
core_useragent::instance(true, 'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) ' .
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile');
// Even if we force the password change for the current user we should be able to retrieve the key.
set_user_preference('auth_forcepasswordchange', 1, $user->id);
@ -240,6 +244,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
global $CFG;
$this->resetAfterTest(true);
// Fake the app.
core_useragent::instance(true, 'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) ' .
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile');
// Need to disable webservices to verify that's checked.
$CFG->enablewebservices = 0;
$CFG->enablemobilewebservice = 0;
@ -256,6 +264,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
public function test_get_autologin_key_missing_https() {
global $CFG;
// Fake the app.
core_useragent::instance(true, 'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) ' .
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile');
// Need to simulate a non HTTPS site here.
$CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot);
@ -276,6 +288,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
$this->resetAfterTest(true);
$this->setAdminUser();
// Fake the app.
core_useragent::instance(true, 'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) ' .
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile');
$this->expectException('moodle_exception');
$this->expectExceptionMessage(get_string('autologinnotallowedtoadmins', 'tool_mobile'));
$result = external::get_autologin_key('');
@ -296,6 +312,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
$token = external_generate_token_for_current_user($service);
$_GET['wstoken'] = $token->token; // Mock parameters.
// Fake the app.
core_useragent::instance(true, 'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) ' .
'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile');
$result = external::get_autologin_key($token->privatetoken);
$result = external_api::clean_returnvalue(external::get_autologin_key_returns(), $result);
@ -311,6 +331,20 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
$result = external::get_autologin_key($token->privatetoken);
}
/**
* Test get_autologin_key missing app_request.
*/
public function test_get_autologin_key_missing_app_request() {
global $CFG;
$this->resetAfterTest(true);
$this->setAdminUser();
$this->expectException('moodle_exception');
$this->expectExceptionMessage(get_string('apprequired', 'tool_mobile'));
$result = external::get_autologin_key('');
}
/**
* Test get_content.
*/

View File

@ -4,6 +4,11 @@ Information provided here is intended especially for developers.
=== 3.7 ===
* New external function tool_mobile::tool_mobile_call_external_function allows calling multiple external functions and returns all responses.
* External function tool_mobile::get_autologin_key now only works if the request comes from the Moodle mobile or desktop app.
This increases confidence that requests did originate from the mobile app, decreasing the likelihood of an XSS attack.
If you want to use this functionality, please override the Web Service via the override_webservice_execution callback although
this is not recommended or encouraged.
>>>>>>> a7ccde5003f... MDL-65075 tool_mobile: Allow auto-login keys only for requests from Moodle apps
=== 3.5 ===