first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Checks status of antivirus scanners by looking back at any recent scans.
*
* @package core
* @category check
* @author Kevin Pham <kevinpham@catalyst-au.net>
* @copyright Catalyst IT, 2021
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class antivirus extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_antivirus_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php', ['section' => 'manageantiviruses']),
get_string('antivirussettings', 'antivirus'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG, $DB;
$details = \html_writer::tag('p', get_string('check_antivirus_details', 'report_security'));
// If no scanners are enabled, then return an NA status since the results do not matter.
if (empty($CFG->antiviruses)) {
$status = result::NA;
$summary = get_string('check_antivirus_info', 'report_security');
return new result($status, $summary, $details);
}
$logmanager = get_log_manager();
$readers = $logmanager->get_readers('\core\log\sql_internal_table_reader');
// If reader is not a sql_internal_table_reader return UNKNOWN since we
// aren't able to fetch the required information. Legacy logs are not
// supported here. They do not hold enough adequate information to be
// used for these checks.
if (empty($readers)) {
$status = result::UNKNOWN;
$summary = get_string('check_antivirus_logstore_not_supported', 'report_security');
return new result($status, $summary, $details);
}
$reader = reset($readers);
// If there has been a recent timestamp within threshold period, then
// set the status to ERROR and describe the problem, e.g. X issues in
// the last N period.
$threshold = get_config('antivirus', 'threshold');
$params = [];
$params['lookback'] = time() - $threshold;
// Type of "targets" to include.
list($targetsqlin, $inparams) = $DB->get_in_or_equal([
'antivirus_scan_file',
'antivirus_scan_data',
], SQL_PARAMS_NAMED);
$params = array_merge($inparams, $params);
// Specify criteria for search.
$selectwhere = "timecreated > :lookback
AND target $targetsqlin
AND action = 'error'";
$totalerrors = $reader->get_events_select_count($selectwhere, $params);
if (!empty($totalerrors)) {
$status = result::ERROR;
$summary = get_string('check_antivirus_error', 'report_security', [
'errors' => $totalerrors,
'lookback' => format_time($threshold)
]);
} else if (!empty($CFG->antiviruses)) {
$status = result::OK;
// Fetch count of enabled antiviruses (we don't care about which ones).
$totalantiviruses = !empty($CFG->antiviruses) ? count(explode(',', $CFG->antiviruses)) : 0;
$summary = get_string('check_antivirus_ok', 'report_security', [
'scanners' => $totalantiviruses,
'lookback' => format_time($threshold)
]);
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,70 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Verifies config.php is not writable anymore after installation
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies config.php is not writable anymore after installation
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class configrw extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_configrw_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_configrw_details', 'report_security');
if (is_writable($CFG->dirroot . '/config.php')) {
$status = result::WARNING;
$summary = get_string('check_configrw_warning', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_configrw_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,75 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Verifies displaying 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)
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
use core\check\check;
/**
* Verifies displaying 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)
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class displayerrors extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_displayerrors_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
$details = get_string('check_displayerrors_details', 'report_security');
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
$status = result::WARNING;
$summary = get_string('check_displayerrors_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_displayerrors_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,83 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Environment check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Environment check
*
* @package core
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class environment extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('environment', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/environment.php'),
get_string('environment', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require_once($CFG->libdir.'/environmentlib.php');
list($status, $details) = check_moodle_environment($CFG->release, ENV_SELECT_NEWER);
if ($status) {
$summary = get_string('environmentok', 'admin');
$status = result::OK;
} else {
$summary = get_string('environmenterrortodo', 'admin');
$status = result::ERROR;
}
return new result($status, $summary, '');
}
}
@@ -0,0 +1,69 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Verifies the status of preventexecpath
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies the status of preventexecpath
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class preventexecpath extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_preventexecpath_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_preventexecpath_details', 'report_security');
if (empty($CFG->preventexecpath)) {
$status = result::WARNING;
$summary = get_string('check_preventexecpath_warning', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_preventexecpath_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,307 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Check the presence of public paths via curl.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Check the public access of various paths.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class publicpaths extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_publicpaths_name', 'report_security');
}
/**
* Returns a list of test urls and metadata.
*/
public function get_pathsets() {
global $CFG;
// The intention here is that each pattern is a simple regex such that
// in future perhaps the various webserver config could be generated as more
// pattens are added to these checks.
return [
[
'pattern' => '/vendor/',
'404' => [
'vendor/',
'vendor/bin/behat',
],
'details' => get_string('check_vendordir_details', 'report_security', ['path' => $CFG->dirroot.'/vendor']),
'summary' => get_string('check_vendordir_info', 'report_security'),
],
[
'pattern' => '/node_modules/',
'404' => [
'node_modules/',
'node_modules/cli/cli.js',
],
'summary' => get_string('check_nodemodules_info', 'report_security'),
'details' => get_string('check_nodemodules_details', 'report_security',
['path' => $CFG->dirroot . '/node_modules']),
],
[
'pattern' => '^\..*',
'404' => [
'.git/',
'.git/HEAD',
'.github/FUNDING.yml',
'.stylelintrc',
],
],
[
'pattern' => 'composer.json',
'404' => [
'composer.json',
],
],
[
'pattern' => '.lock',
'404' => [
'composer.lock',
],
],
[
'pattern' => 'environment.xml',
'404' => [
'admin/environment.xml',
],
],
[
'pattern' => '',
'404' => [
'doesnotexist', // Just to make sure that real 404s are still 404s.
],
'summary' => '',
],
[
'pattern' => '',
'404' => [
'lib/classes/',
],
'summary' => get_string('check_dirindex_info', 'report_security'),
],
[
'pattern' => 'db/install.xml',
'404' => [
'lib/db/install.xml',
'mod/assign/db/install.xml',
],
],
[
'pattern' => 'readme.txt',
'404' => [
'lib/scssphp/readme_moodle.txt',
'mod/resource/readme.txt',
],
],
[
'pattern' => 'README',
'404' => [
'mod/README.txt',
'mod/book/README.md',
'mod/chat/README.txt',
],
],
[
'pattern' => '/upgrade.txt',
'404' => [
'auth/manual/upgrade.txt',
'lib/upgrade.txt',
],
],
[
'pattern' => 'phpunit.xml',
'404' => ['phpunit.xml.dist'],
],
[
'pattern' => '/fixtures/',
'404' => [
'privacy/tests/fixtures/logo.png',
'enrol/lti/tests/fixtures/input.xml',
],
],
[
'pattern' => '/behat/',
'404' => ['blog/tests/behat/delete.feature'],
],
];
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG, $OUTPUT;
$status = result::OK;
$details = '';
$summary = get_string('check_publicpaths_ok', 'report_security');
$errors = [];
$c = new \curl();
$paths = $this->get_pathsets();
$table = new \html_table();
$table->align = ['center', 'right', 'left'];
$table->size = ['1%', '1%', '1%', '1%', '1%', '99%'];
$table->head = [
get_string('status'),
get_string('checkexpected'),
get_string('checkactual'),
get_string('url'),
get_string('category'),
get_string('details'),
];
$table->attributes['class'] = 'flexible generaltable generalbox table-sm';
$table->data = [];
// Used to track duplicated errors.
$lastdetail = '-';
$curl = new \curl();
$requests = [];
// Build up a list of all url so we can load them in parallel.
foreach ($paths as $path) {
foreach (['200', '404'] as $expected) {
if (!isset($path[$expected])) {
continue;
}
foreach ($path[$expected] as $test) {
$requests[] = [
'nobody' => true,
'header' => 1,
'url' => $CFG->wwwroot . '/' . $test,
'returntransfer' => true,
];
}
}
}
$headers = $curl->download($requests);
foreach ($paths as $path) {
foreach (['200', '404'] as $expected) {
if (!isset($path[$expected])) {
continue;
}
foreach ($path[$expected] as $test) {
$rowsummary = '';
$rowdetail = '';
$url = $CFG->wwwroot . '/' . $test;
// Parse the HTTP header to get the 200 / 404 code.
$header = array_shift($headers);
$actual = strtok($header, "\n");
$actual = strtok($actual, " ");
$actual = strtok(" ");
if ($actual != $expected) {
if (isset($path['summary'])) {
$rowsummary = $path['summary'];
} else {
$rowsummary = get_string('check_publicpaths_generic',
'report_security', $path['pattern']);
}
// Special case where a 404 is ideal but a 403 is ok too.
if ($actual == 403) {
$result = new result(result::INFO, '', '');
$rowsummary .= get_string('check_publicpaths_403', 'report_security');
} else {
$result = new result(result::ERROR, '', '');
$status = result::ERROR;
$summary = get_string('check_publicpaths_warning', 'report_security');
}
$rowdetail = isset($path['details']) ? $path['details'] : $rowsummary;
if (empty($errors[$path['pattern']])) {
$summary .= '<li>' . $rowsummary . '</li>';
$errors[$path['pattern']] = 1;
}
} else {
$result = new result(result::OK, '', '');
}
$table->data[] = [
$OUTPUT->check_result($result),
$expected,
$actual,
$OUTPUT->action_link($url, $test, null, ['target' => '_blank']),
"<pre>{$path['pattern']}</pre>",
];
// Merge duplicate details to display a nicer table.
if ($rowdetail == $lastdetail) {
$duplicates++;
} else {
$duplicates = 1;
}
$detailcell = new \html_table_cell($rowdetail);
$detailcell->rowspan = $duplicates;
$rows = count($table->data);
$table->data[$rows - $duplicates][5] = $detailcell;
$lastdetail = $rowdetail;
}
}
}
$details .= \html_writer::table($table);
return new result($status, $summary, $details);
}
/**
* Link to the dev docs for more info.
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url(\get_docs_url('Installing_Moodle#Set_up_your_server')),
get_string('moodledocs'));
}
}
@@ -0,0 +1,80 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Verifies fatal misconfiguration of dataroot
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
/**
* Verifies fatal misconfiguration of dataroot
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class unsecuredataroot extends \core\check\check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_unsecuredataroot_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require_once($CFG->libdir.'/adminlib.php');
$details = get_string('check_unsecuredataroot_details', 'report_security');
$insecuredataroot = is_dataroot_insecure(true);
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
$status = result::ERROR;
$summary = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
$status = result::CRITICAL;
$summary = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
} else {
$status = result::OK;
$summary = get_string('check_unsecuredataroot_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,85 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Upgrade check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Upgrade check
*
* @package core
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class upgradecheck extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('checkupgradepending', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/index.php?cache=1'),
get_string('notifications', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require("$CFG->dirroot/version.php");
$newversion = "$release ($version)";
if ($version < $CFG->version) {
$status = result::ERROR;
$summary = get_string('downgradedcore', 'error');
} else if (moodle_needs_upgrading()) {
$status = result::ERROR;
$summary = get_string('cliupgradepending', 'admin');
} else {
$status = result::OK;
$summary = get_string('cliupgradenoneed', 'core_admin', $newversion);
}
return new result($status, $summary);
}
}