Skip to content

Commit

Permalink
MDL-72486 core: Add unsafe log and fix options to proxy settings
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanheywood committed Jun 20, 2022
1 parent b81fb00 commit 9fa26ed
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
5 changes: 5 additions & 0 deletions admin/settings/server.php
Expand Up @@ -172,6 +172,11 @@
new lang_string('configproxypassword', 'admin'), ''));
$temp->add(new admin_setting_configtext('proxybypass', new lang_string('proxybypass', 'admin'),
new lang_string('configproxybypass', 'admin'), 'localhost, 127.0.0.1'));
$temp->add(new admin_setting_configcheckbox('proxylogunsafe', new lang_string('proxylogunsafe', 'admin'),
new lang_string('configproxylogunsafe_help', 'admin'), 0));
$temp->add(new admin_setting_configcheckbox('proxyfixunsafe', new lang_string('proxyfixunsafe', 'admin'),
new lang_string('configproxyfixunsafe_help', 'admin'), 0));

$ADMIN->add('server', $temp);

$temp = new admin_settingpage('maintenancemode', new lang_string('sitemaintenancemode', 'admin'));
Expand Down
4 changes: 4 additions & 0 deletions lang/en/admin.php
Expand Up @@ -326,6 +326,8 @@
$string['configproxyport'] = 'If this server needs to use a proxy computer, then provide the proxy port here.';
$string['configproxytype'] = 'Type of web proxy (PHP5 and cURL extension required for SOCKS5 support).';
$string['configproxyuser'] = 'Username needed to access internet through proxy if required, empty if none (PHP cURL extension required).';
$string['configproxyfixunsafe_help'] = 'This attempts to fix internal calls which do not go through the proxy by adding the MoodleBot User Agent and using the proxy.';
$string['configproxylogunsafe_help'] = 'This attempts to log internal calls which do not go through the proxy and should.';
$string['configrecaptchaprivatekey'] = 'String of characters (secret key) used to communicate between your Moodle server and the recaptcha server. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
$string['configrecaptchapublickey'] = 'String of characters (site key) used to display the reCAPTCHA element in the signup form and site support form. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
$string['configrequestedstudentname'] = 'Word for student used in requested courses';
Expand Down Expand Up @@ -1071,6 +1073,8 @@
$string['proxyport'] = 'Proxy port';
$string['proxytype'] = 'Proxy type';
$string['proxyuser'] = 'Proxy username';
$string['proxylogunsafe'] = 'Log unproxied calls';
$string['proxyfixunsafe'] = 'Fix unproxied calls';
$string['query'] = 'Query';
$string['question'] = 'Question';
$string['questionbehaviours'] = 'Question behaviours';
Expand Down
32 changes: 32 additions & 0 deletions lib/filelib.php
Expand Up @@ -3052,6 +3052,38 @@ function file_is_svg_image_from_mimetype(string $mimetype): bool {
return preg_match('|^image/svg|', $mimetype);
}

/**
* Returns the moodle proxy configuration as a formatted url
*
* @return string the string to use for proxy settings.
*/
function get_moodle_proxy_url() {
global $CFG;
$proxy = '';
if (empty($CFG->proxytype)) {
return $proxy;
}
if (empty($CFG->proxyhost)) {
return $proxy;
}
if ($CFG->proxytype === 'SOCKS5') {
// If it is a SOCKS proxy, append the protocol info.
$protocol = 'socks5://';
} else {
$protocol = '';
}
$proxy = $CFG->proxyhost;
if (!empty($CFG->proxyport)) {
$proxy .= ':'. $CFG->proxyport;
}
if (!empty($CFG->proxyuser) && !empty($CFG->proxypassword)) {
$proxy = $protocol . $CFG->proxyuser . ':' . $CFG->proxypassword . '@' . $proxy;
}
return $proxy;
}



/**
* RESTful cURL class
*
Expand Down
29 changes: 29 additions & 0 deletions lib/setup.php
Expand Up @@ -828,6 +828,35 @@
}
\core\session\manager::start();

if (!empty($CFG->proxylogunsafe) || !empty($CFG->proxyfixunsafe)) {
if (!empty($CFG->proxyfixunsafe)) {
require_once($CFG->libdir.'/filelib.php');

$proxyurl = get_moodle_proxy_url();
// This fixes stream handlers inside php.
$defaults = stream_context_set_default([
'http' => [
'user_agent' => \core_useragent::get_moodlebot_useragent(),
'proxy' => $proxyurl
],
]);

// Attempt to tell other web clients to use the proxy too. This only
// works for clients written in php in the same process, it will not
// work for with requests done in another process from an exec call.
putenv('http_proxy=' . $proxyurl);
putenv('https_proxy=' . $proxyurl);
putenv('HTTPS_PROXY=' . $proxyurl);
} else {
$defaults = stream_context_get_default();
}

if (!empty($CFG->proxylogunsafe)) {
stream_context_set_params($defaults, ['notification' => 'proxy_log_callback']);
}

}

// Set default content type and encoding, developers are still required to use
// echo $OUTPUT->header() everywhere, anything that gets set later should override these headers.
// This is intended to mitigate some security problems.
Expand Down
18 changes: 18 additions & 0 deletions lib/setuplib.php
Expand Up @@ -2172,3 +2172,21 @@ public static function plain_page($title, $content, $meta = '') {
return $html;
}
}

/**
* Add http stream instrumentation
*
* This detects which any reads or writes to a php stream which uses
* the 'http' handler. Ideally 100% of traffic uses the Moodle curl
* libraries which do not use php streams.
*
* @param array $code stream callback code
*/
function proxy_log_callback($code) {
if ($code == STREAM_NOTIFY_CONNECT) {
$trace = debug_backtrace();
$function = $trace[count($trace) - 1];
$error = "Unsafe internet IO detected: {$function['function']} with arguments " . join(', ', $function['args']) . "\n";
error_log($error . format_backtrace($trace, true)); // phpcs:ignore
}
}
1 change: 1 addition & 0 deletions lib/upgrade.txt
Expand Up @@ -21,6 +21,7 @@ information provided here is intended especially for developers.
Moodle version the plugin is incompatible with but the implemented logic for the check was the opposite. Plugins declaring this
attribute may encounter different behaviours between older Moodle versions (<v3.11.8, <v4.0.2) and the later ones. We recommend
plugin developers to not use this attribute for Moodle versions 4.0 and below in order to avoid this problem.
* Added $CFG->proxylogunsafe and proxyfixunsafe to detect code which doesn't honor the proxy config

=== 4.0 ===

Expand Down

0 comments on commit 9fa26ed

Please sign in to comment.