diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 0f9cc5f7cfa10..63ae7a0105789 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -1029,10 +1029,16 @@ function clean_param($param, $type) { // Allow http absolute, root relative and relative URLs within wwwroot. $param = clean_param($param, PARAM_URL); if (!empty($param)) { + + // Simulate the HTTPS version of the site. + $httpswwwroot = str_replace('http://', 'https://', $CFG->wwwroot); + if (preg_match(':^/:', $param)) { // Root-relative, ok! - } else if (preg_match('/^'.preg_quote($CFG->wwwroot, '/').'/i', $param)) { + } else if (preg_match('/^' . preg_quote($CFG->wwwroot, '/') . '/i', $param)) { // Absolute, and matches our wwwroot. + } else if (!empty($CFG->loginhttps) && preg_match('/^' . preg_quote($httpswwwroot, '/') . '/i', $param)) { + // Absolute, and matches our httpswwwroot. } else { // Relative - let's make sure there are no tricks. if (validateUrlSyntax('/' . $param, 's-u-P-a-p-f+q?r?')) { diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 8b4a52d8b816c..85b449616eecd 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -583,12 +583,32 @@ public function test_clean_param_url() { public function test_clean_param_localurl() { global $CFG; + // External, invalid. + $this->assertSame('', clean_param('funny:thing', PARAM_LOCALURL)); $this->assertSame('', clean_param('http://google.com/', PARAM_LOCALURL)); + $this->assertSame('', clean_param('https://google.com/?test=true', PARAM_LOCALURL)); $this->assertSame('', clean_param('http://some.very.long.and.silly.domain/with/a/path/', PARAM_LOCALURL)); + + // Local absolute. $this->assertSame(clean_param($CFG->wwwroot, PARAM_LOCALURL), $CFG->wwwroot); + $this->assertSame($CFG->wwwroot . '/with/something?else=true', + clean_param($CFG->wwwroot . '/with/something?else=true', PARAM_LOCALURL)); + + // Local relative. $this->assertSame('/just/a/path', clean_param('/just/a/path', PARAM_LOCALURL)); - $this->assertSame('', clean_param('funny:thing', PARAM_LOCALURL)); $this->assertSame('course/view.php?id=3', clean_param('course/view.php?id=3', PARAM_LOCALURL)); + + // Local absolute HTTPS. + $httpsroot = str_replace('http:', 'https:', $CFG->wwwroot); + $initialloginhttps = $CFG->loginhttps; + $CFG->loginhttps = false; + $this->assertSame('', clean_param($httpsroot, PARAM_LOCALURL)); + $this->assertSame('', clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); + $CFG->loginhttps = true; + $this->assertSame($httpsroot, clean_param($httpsroot, PARAM_LOCALURL)); + $this->assertSame($httpsroot . '/with/something?else=true', + clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); + $CFG->loginhttps = $initialloginhttps; } public function test_clean_param_file() {