libdir/adminlib.php");
define('REPORT_SECURITY_OK', 'ok');
define('REPORT_SECURITY_INFO', 'info');
define('REPORT_SECURITY_WARNING', 'warning');
define('REPORT_SECURITY_SERIOUS', 'serious');
define('REPORT_SECURITY_CRITICAL', 'critical');
function report_security_hide_timearning() {
echo '';
}
function report_security_get_issue_list() {
return array(
'report_security_check_globals',
'report_security_check_unsecuredataroot',
'report_security_check_displayerrors',
'report_security_check_noauth',
'report_security_check_embed',
'report_security_check_mediafilterswf',
'report_security_check_openprofiles',
'report_security_check_google',
'report_security_check_passwordpolicy',
'report_security_check_passwordsaltmain',
'report_security_check_emailchangeconfirmation',
'report_security_check_cookiesecure',
'report_security_check_configrw',
'report_security_check_riskxss',
'report_security_check_riskadmin',
'report_security_check_riskbackup',
'report_security_check_defaultuserrole',
'report_security_check_guestrole',
'report_security_check_frontpagerole',
'report_security_check_defaultcourserole',
'report_security_check_courserole',
);
}
function report_security_doc_link($issue, $name) {
global $CFG;
if (empty($CFG->docroot)) {
return $name;
}
$lang = str_replace('_utf8', '', current_language());
$str = "docroot/$lang/report/security/$issue\">";
$str .= "httpswwwroot/pix/docs.gif\" alt=\"\" />$name";
return $str;
}
///=============================================
/// Issue checks
///=============================================
/**
* Verifies register globals PHP setting.
* @param bool $detailed
* @return object result
*/
function report_security_check_globals($detailed=false) {
$result = new object();
$result->issue = 'report_security_check_globals';
$result->name = get_string('check_globals_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (ini_get_bool('register_globals')) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_globals_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_globals_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_globals_details', 'report_security');
}
return $result;
}
/**
* Verifies unsupported noauth setting
* @param bool $detailed
* @return object result
*/
function report_security_check_noauth($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_noauth';
$result->name = get_string('check_noauth_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=manageauths\">".get_string('authsettings', 'admin').'';
if (is_enabled_auth('none')) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_noauth_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_noauth_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_noauth_details', 'report_security');
}
return $result;
}
/**
* Verifies if password policy set
* @param bool $detailed
* @return object result
*/
function report_security_check_passwordpolicy($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_passwordpolicy';
$result->name = get_string('check_passwordpolicy_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'';
if (empty($CFG->passwordpolicy)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordpolicy_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_passwordpolicy_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_passwordpolicy_details', 'report_security');
}
return $result;
}
/**
* Verifies sloppy embedding - this should have been removed long ago!!
* @param bool $detailed
* @return object result
*/
function report_security_check_embed($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_embed';
$result->name = get_string('check_embed_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'';
if (!empty($CFG->allowobjectembed)) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_embed_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_embed_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_embed_details', 'report_security');
}
return $result;
}
/**
* Verifies sloppy swf embedding - this should have been removed long ago!!
* @param bool $detailed
* @return object result
*/
function report_security_check_mediafilterswf($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_mediafilterswf';
$result->name = get_string('check_mediafilterswf_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=filtersettingfiltermediaplugin\">".get_string('filtersettings', 'admin').'';
if (!empty($CFG->textfilters)) {
$activefilters = explode(',', $CFG->textfilters);
} else {
$activefilters = array();
}
if (array_search('filter/mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_mediafilterswf_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_mediafilterswf_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_mediafilterswf_details', 'report_security');
}
return $result;
}
/**
* Verifies fatal misconfiguration of dataroot
* @param bool $detailed
* @return object result
*/
function report_security_check_unsecuredataroot($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_unsecuredataroot';
$result->name = get_string('check_unsecuredataroot_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$insecuredataroot = is_dataroot_insecure(true);
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_unsecuredataroot_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_unsecuredataroot_details', 'report_security');
}
return $result;
}
/**
* Verifies disaplying of errors - problem for lib files and 3rd party code
* because we can not disable debugging in these scripts (they do not include config.php)
* @param bool $detailed
* @return object result
*/
function report_security_check_displayerrors($detailed=false) {
$result = new object();
$result->issue = 'report_security_check_displayerrors';
$result->name = get_string('check_displayerrors_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_displayerrors_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_displayerrors_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_displayerrors_details', 'report_security');
}
return $result;
}
/**
* Verifies open profiles - originaly open by default, not anymore because spammer abused it a lot
* @param bool $detailed
* @return object result
*/
function report_security_check_openprofiles($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_openprofiles';
$result->name = get_string('check_openprofiles_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'';
if (empty($CFG->forcelogin) and empty($CFG->forceloginforprofiles)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_openprofiles_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_openprofiles_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_openprofiles_details', 'report_security');
}
return $result;
}
/**
* Verifies google access not combined with disabled guest access
* because attackers might gain guest access by modifying browser signature.
* @param bool $detailed
* @return object result
*/
function report_security_check_google($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_google';
$result->name = get_string('check_google_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'';
if (empty($CFG->opentogoogle)) {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_google_ok', 'report_security');
} else if (!empty($CFG->guestloginbutton)) {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_google_info', 'report_security');
} else {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_google_error', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_google_details', 'report_security');
}
return $result;
}
/**
* Verifies email confirmation - spammers were changing mails very often
* @param bool $detailed
* @return object result
*/
function report_security_check_emailchangeconfirmation($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_emailchangeconfirmation';
$result->name = get_string('check_emailchangeconfirmation_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'';
if (empty($CFG->emailchangeconfirmation)) {
if (empty($CFG->allowemailaddresses)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_emailchangeconfirmation_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_emailchangeconfirmation_info', 'report_security');
}
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_emailchangeconfirmation_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_emailchangeconfirmation_details', 'report_security');
}
return $result;
}
/**
* Verifies if https enabled only secure cookies allowed,
* this prevents redirections and sending of cookies to unsecure port.
* @param bool $detailed
* @return object result
*/
function report_security_check_cookiesecure($detailed=false) {
global $CFG;
if (strpos($CFG->wwwroot, 'https://') !== 0) {
return null;
}
$result = new object();
$result->issue = 'report_security_check_cookiesecure';
$result->name = get_string('check_cookiesecure_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=httpsecurity\">".get_string('httpsecurity', 'admin').'';
if (empty($CFG->cookiesecure)) {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_cookiesecure_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_cookiesecure_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_cookiesecure_details', 'report_security');
}
return $result;
}
/**
* Verifies config.php is not writable anymore after installation,
* config files were changed on several outdated server.
* @param bool $detailed
* @return object result
*/
function report_security_check_configrw($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_configrw';
$result->name = get_string('check_configrw_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (is_writable($CFG->dirroot.'/config.php')) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_configrw_warning', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_configrw_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_configrw_details', 'report_security');
}
return $result;
}
function report_security_check_passwordsaltmain($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_passwordsaltmain';
$result->name = get_string('check_passwordsaltmain_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (empty($CFG->passwordsaltmain)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordsaltmain_warning', 'report_security');
} else if ($CFG->passwordsaltmain === 'some long random string here with lots of characters'
|| trim($CFG->passwordsaltmain) === '' || preg_match('/^([a-z0-9]{0,10})$/i', $CFG->passwordsaltmain)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordsaltmain_weak', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_passwordsaltmain_ok', 'report_security');
}
if ($detailed) {
$docspath = $CFG->docroot.'/'.str_replace('_utf8', '', current_language()).'/report/security/report_security_check_passwordsaltmain';
$result->details = get_string('check_passwordsaltmain_details', 'report_security', $docspath);
}
return $result;
}
/**
* Lists all users with XSS risk, it would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
* @param bool $detailed
* @return object result
*/
function report_security_check_riskxss($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_riskxss';
$result->name = get_string('check_riskxss_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = REPORT_SECURITY_WARNING;
$result->link = null;
$sqlfrom = "FROM (SELECT rcx.*
FROM {$CFG->prefix}role_capabilities rcx
JOIN {$CFG->prefix}capabilities cap ON (cap.name = rcx.capability AND ".sql_bitand('cap.riskbitmask', RISK_XSS)." <> 0)
WHERE rcx.permission = ".CAP_ALLOW.") rc,
{$CFG->prefix}context c,
{$CFG->prefix}context sc,
{$CFG->prefix}role_assignments ra,
{$CFG->prefix}user u
WHERE c.id = rc.contextid
AND (sc.path = c.path OR sc.path LIKE ".sql_concat('c.path', "'/%'")." OR c.path LIKE ".sql_concat('sc.path', "'/%'").")
AND u.id = ra.userid AND u.deleted = 0
AND ra.contextid = sc.id AND ra.roleid = rc.roleid";
$count = count_records_sql("SELECT COUNT(DISTINCT u.id) $sqlfrom");
$result->info = get_string('check_riskxss_warning', 'report_security', $count);
if ($detailed) {
$users = get_records_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt $sqlfrom");
foreach ($users as $uid=>$user) {
$users[$uid] = fullname($user);
}
$users = implode(', ', $users);
$result->details = get_string('check_riskxss_details', 'report_security', $users);
}
return $result;
}
/**
* Verifies sanity of default user role.
* @param bool $detailed
* @return object result
*/
function report_security_check_defaultuserrole($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_defaultuserrole';
$result->name = get_string('check_defaultuserrole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'';;
if (!$default_role = get_record('role', 'id', $CFG->defaultuserroleid)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_defaultuserrole_notset', 'report_security');
$result->details = $result->info;
return $result;
}
// first test if do anything enabled - that would be really crazy!
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability = 'moodle/site:doanything'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $default_role->id";
$anythingcount = count_records_sql($sql);
// risky caps - usually very dangerous
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
JOIN {$CFG->prefix}capabilities cap ON cap.name = rc.capability
WHERE ".sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $default_role->id";
$riskycount = count_records_sql($sql);
// default role can not have view cap in all courses - this would break moodle badly
$viewcap = record_exists('role_capabilities', 'roleid', $default_role->id, 'permission', CAP_ALLOW, 'capability', 'moodle/course:view');
// it may have either no or 'user' legacy type - nothing else, or else it would break during upgrades badly
$legacyok = false;
$sql = "SELECT rc.capability, 1
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability LIKE 'moodle/legacy:%'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $default_role->id";
$legacycaps = get_records_sql($sql);
if (!$legacycaps) {
$legacyok = true;
} else if (count($legacycaps) == 1 and isset($legacycaps['moodle/legacy:user'])) {
$legacyok = true;
}
if ($anythingcount or $riskycount or $viewcap or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_defaultuserrole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_defaultuserrole_details', 'report_security');
}
return $result;
}
/**
* Verifies sanity of guest role
* @param bool $detailed
* @return object result
*/
function report_security_check_guestrole($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_guestrole';
$result->name = get_string('check_guestrole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'';;
if (!$guest_role = get_record('role', 'id', $CFG->guestroleid)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_guestrole_notset', 'report_security');
$result->details = $result->info;
return $result;
}
// first test if do anything enabled - that would be really crazy!
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability = 'moodle/site:doanything'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $guest_role->id";
$anythingcount = count_records_sql($sql);
// risky caps - usually very dangerous
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
JOIN {$CFG->prefix}capabilities cap ON cap.name = rc.capability
WHERE ".sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $guest_role->id";
$riskycount = count_records_sql($sql);
// it may have either no or 'guest' legacy type - nothing else, or else it would break during upgrades badly
$legacyok = false;
$sql = "SELECT rc.capability, 1
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability LIKE 'moodle/legacy:%'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $guest_role->id";
$legacycaps = get_records_sql($sql);
if (!$legacycaps) {
$legacyok = true;
} else if (count($legacycaps) == 1 and isset($legacycaps['moodle/legacy:guest'])) {
$legacyok = true;
}
if ($anythingcount or $riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_guestrole_error', 'report_security', format_string($guest_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_guestrole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_guestrole_details', 'report_security');
}
return $result;
}
/**
* Verifies sanity of frontpage role
* @param bool $detailed
* @return object result
*/
function report_security_check_frontpagerole($detailed=false) {
global $CFG;
$result = new object();
$result->issue = 'report_security_check_frontpagerole';
$result->name = get_string('check_frontpagerole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=frontpagesettings\">".get_string('frontpagesettings','admin').'';;
if (!$frontpage_role = get_record('role', 'id', $CFG->defaultfrontpageroleid)) {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_frontpagerole_notset', 'report_security');
$result->details = get_string('check_frontpagerole_details', 'report_security');
return $result;
}
// first test if do anything enabled - that would be really crazy!
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability = 'moodle/site:doanything'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $frontpage_role->id";
$anythingcount = count_records_sql($sql);
// risky caps - usually very dangerous
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {$CFG->prefix}role_capabilities rc
JOIN {$CFG->prefix}capabilities cap ON cap.name = rc.capability
WHERE ".sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $frontpage_role->id";
$riskycount = count_records_sql($sql);
// there is no legacy role type for frontpage yet - anyway we can not allow teachers or admins there!
$sql = "SELECT rc.capability, 1
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability LIKE 'moodle/legacy:%'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $frontpage_role->id";
$legacycaps = get_records_sql($sql);
$legacyok = (!isset($legacycaps['moodle/legacy:teacher'])
and !isset($legacycaps['moodle/legacy:editingteacher'])
and !isset($legacycaps['moodle/legacy:coursecreator'])
and !isset($legacycaps['moodle/legacy:admin']));
if ($anythingcount or $riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_frontpagerole_error', 'report_security', format_string($frontpage_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_frontpagerole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_frontpagerole_details', 'report_security');
}
return $result;
}
/**
* Verifies sanity of site default course role.
* @param bool $detailed
* @return object result
*/
function report_security_check_defaultcourserole($detailed=false) {
global $CFG;
$problems = array();
$result = new object();
$result->issue = 'report_security_check_defaultcourserole';
$result->name = get_string('check_defaultcourserole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'';;
if ($detailed) {
$result->details = get_string('check_defaultcourserole_details', 'report_security');
}
if (!$student_role = get_record('role', 'id', $CFG->defaultcourseroleid)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_defaultcourserole_notset', 'report_security');
$result->details = get_string('check_defaultcourserole_details', 'report_security');
return $result;
}
// first test if do anything enabled - that would be really crazy!
$sql = "SELECT DISTINCT rc.contextid
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability = 'moodle/site:doanything'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $student_role->id";
if ($anything_contexts = get_records_sql($sql)) {
foreach($anything_contexts as $contextid) {
if ($contextid == SYSCONTEXTID) {
$a = "$CFG->wwwroot/$CFG->admin/roles/manage.php?action=view&roleid=$CFG->defaultcourseroleid";
} else {
$a = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid&roleid=$CFG->defaultcourseroleid";
}
$problems[] = get_string('check_defaultcourserole_anything', 'report_security', $a);
}
}
// risky caps - usually very dangerous
$sql = "SELECT DISTINCT rc.contextid
FROM {$CFG->prefix}role_capabilities rc
JOIN {$CFG->prefix}capabilities cap ON cap.name = rc.capability
WHERE ".sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $student_role->id";
if ($riskycontexts = get_records_sql($sql)) {
foreach($riskycontexts as $contextid=>$unused) {
if ($contextid == SYSCONTEXTID) {
$a = "$CFG->wwwroot/$CFG->admin/roles/manage.php?action=view&roleid=$CFG->defaultcourseroleid";
} else {
$a = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid&roleid=$CFG->defaultcourseroleid";
}
$problems[] = get_string('check_defaultcourserole_risky', 'report_security', $a);
}
}
// course creator or administrator does not make any sense here
$sql = "SELECT rc.capability, 1
FROM {$CFG->prefix}role_capabilities rc
WHERE rc.capability LIKE 'moodle/legacy:%'
AND rc.permission = ".CAP_ALLOW."
AND rc.roleid = $student_role->id";
$legacycaps = get_records_sql($sql);
if (isset($legacycaps['moodle/legacy:coursecreator']) or isset($legacycaps['moodle/legacy:admin'])) {
$problems[] = get_string('check_defaultcourserole_legacy', 'report_security');
}
if ($problems) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_defaultcourserole_error', 'report_security', format_string($student_role->name));
if ($detailed) {
$result->details .= "