UploadExtensions.php in Security Review 8
File
src/Checks/UploadExtensions.php
View source
<?php
namespace Drupal\security_review\Checks;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Drupal\security_review\Check;
use Drupal\security_review\CheckResult;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
class UploadExtensions extends Check {
public function getNamespace() {
return 'Security Review';
}
public function getTitle() {
return 'Allowed upload extensions';
}
public function getMachineTitle() {
return 'upload_extensions';
}
public function run() {
if (!$this
->moduleHandler()
->moduleExists('field')) {
return $this
->createResult(CheckResult::INFO);
}
$result = CheckResult::SUCCESS;
$findings = [];
foreach (FieldConfig::loadMultiple() as $entity) {
$extensions = $entity
->getSetting('file_extensions');
if ($extensions != NULL) {
$extensions = explode(' ', $extensions);
$intersect = array_intersect($extensions, $this
->security()
->unsafeExtensions());
foreach ($intersect as $unsafe_extension) {
$findings[$entity
->id()][] = $unsafe_extension;
}
}
}
if (!empty($findings)) {
$result = CheckResult::FAIL;
}
return $this
->createResult($result, $findings);
}
public function help() {
$paragraphs = [];
$paragraphs[] = $this
->t('File and image fields allow for uploaded files. Some extensions are considered dangerous because the files can be evaluated and then executed in the browser. A malicious user could use this opening to gain control of your site. Review <a href=":url">all fields on your site</a>.', [
':url' => Url::fromRoute('entity.field_storage_config.collection')
->toString(),
]);
return [
'#theme' => 'check_help',
'#title' => 'Allowed upload extensions',
'#paragraphs' => $paragraphs,
];
}
public function evaluate(CheckResult $result) {
$findings = $result
->findings();
if (empty($findings)) {
return [];
}
$paragraphs = [];
$paragraphs[] = $this
->t('The following extensions are considered unsafe and should be removed or limited from use. Or, be sure you are not granting untrusted users the ability to upload files.');
$items = [];
foreach ($findings as $entity_id => $unsafe_extensions) {
$entity = FieldConfig::load($entity_id);
foreach ($unsafe_extensions as $extension) {
$item = $this
->t('Review @type in <em>@field</em> field on @bundle', [
'@type' => $extension,
'@field' => $entity
->label(),
'@bundle' => $entity
->getTargetBundle(),
]);
try {
$url_params = [
'field_config' => $entity
->id(),
];
if ($entity
->getTargetEntityTypeId() == 'node') {
$url_params['node_type'] = $entity
->getTargetBundle();
}
$items[] = Link::createFromRoute($item, sprintf('entity.field_config.%s_field_edit_form', $entity
->getTargetEntityTypeId()), $url_params);
} catch (RouteNotFoundException $e) {
$items[] = $item;
}
}
}
return [
'#theme' => 'check_evaluation',
'#paragraphs' => $paragraphs,
'#items' => $items,
];
}
public function evaluatePlain(CheckResult $result) {
$findings = $result
->findings();
if (empty($findings)) {
return '';
}
$output = '';
foreach ($findings as $entity_id => $unsafe_extensions) {
$entity = FieldConfig::load($entity_id);
$output .= $this
->t('@bundle: field @field', [
'@bundle' => $entity
->getTargetBundle(),
'@field' => $entity
->label(),
]);
$output .= "\n\t" . implode(', ', $unsafe_extensions) . "\n";
}
return $output;
}
public function getMessage($result_const) {
switch ($result_const) {
case CheckResult::SUCCESS:
return $this
->t('Only safe extensions are allowed for uploaded files and images.');
case CheckResult::FAIL:
return $this
->t('Unsafe file extensions are allowed in uploads.');
case CheckResult::INFO:
return $this
->t('Module field is not enabled.');
default:
return $this
->t('Unexpected result.');
}
}
}
Classes
Name |
Description |
UploadExtensions |
Checks for unsafe extensions in the allowed extensions settings of fields. |