public function QueryErrors::run in Security Review 8
The actual procedure of carrying out the check.
Return value
\Drupal\security_review\CheckResult The result of running the check.
Overrides Check::run
File
- src/
Checks/ QueryErrors.php, line 31
Class
- QueryErrors
- Checks for abundant query errors.
Namespace
Drupal\security_review\ChecksCode
public function run() {
// If dblog is not enabled return with hidden INFO.
if (!$this
->moduleHandler()
->moduleExists('dblog')) {
return $this
->createResult(CheckResult::INFO, [], FALSE);
}
$result = CheckResult::SUCCESS;
$findings = [];
$last_result = $this
->lastResult();
$visible = FALSE;
// Prepare the query.
$query = $this
->database()
->select('watchdog', 'w');
$query
->fields('w', [
'severity',
'type',
'timestamp',
'message',
'variables',
'hostname',
]);
$query
->condition('type', 'php')
->condition('severity', RfcLogLevel::ERROR);
if ($last_result instanceof CheckResult) {
// Only check entries that got recorded since the last run of the check.
$query
->condition('timestamp', $last_result
->time(), '>=');
}
// Execute the query.
$db_result = $query
->execute();
// Count the number of query errors per IP.
$entries = [];
foreach ($db_result as $row) {
// Get the message.
if ($row->variables === 'N;') {
$message = $row->message;
}
else {
$message = $this
->t($row->message, unserialize($row->variables));
}
// Get the IP.
$ip = $row->hostname;
// Search for query errors.
$message_contains_sql = strpos($message, 'SQL') !== FALSE;
$message_contains_select = strpos($message, 'SELECT') !== FALSE;
if ($message_contains_sql && $message_contains_select) {
$entry_for_ip =& $entries[$ip];
if (!isset($entry_for_ip)) {
$entry_for_ip = 0;
}
$entry_for_ip++;
}
}
// Filter the IPs with more than 10 query errors.
if (!empty($entries)) {
foreach ($entries as $ip => $count) {
if ($count > 10) {
$findings[] = $ip;
}
}
}
if (!empty($findings)) {
$result = CheckResult::FAIL;
$visible = TRUE;
}
return $this
->createResult($result, $findings, $visible);
}