Revision 15:e200cb7efeb3 core/lib/Drupal/Core/Security/RequestSanitizer.php
| core/lib/Drupal/Core/Security/RequestSanitizer.php | ||
|---|---|---|
| 2 | 2 |
|
| 3 | 3 |
namespace Drupal\Core\Security; |
| 4 | 4 |
|
| 5 |
use Drupal\Component\Utility\UrlHelper; |
|
| 6 |
use Symfony\Component\HttpFoundation\ParameterBag; |
|
| 5 | 7 |
use Symfony\Component\HttpFoundation\Request; |
| 6 | 8 |
|
| 7 | 9 |
/** |
| ... | ... | |
| 39 | 41 |
*/ |
| 40 | 42 |
public static function sanitize(Request $request, $whitelist, $log_sanitized_keys = FALSE) {
|
| 41 | 43 |
if (!$request->attributes->get(self::SANITIZED, FALSE)) {
|
| 42 |
// Process query string parameters. |
|
| 43 |
$get_sanitized_keys = []; |
|
| 44 |
$request->query->replace(static::stripDangerousValues($request->query->all(), $whitelist, $get_sanitized_keys)); |
|
| 45 |
if ($log_sanitized_keys && !empty($get_sanitized_keys)) {
|
|
| 46 |
trigger_error(sprintf('Potentially unsafe keys removed from query string parameters (GET): %s', implode(', ', $get_sanitized_keys)));
|
|
| 44 |
$update_globals = FALSE; |
|
| 45 |
$bags = [ |
|
| 46 |
'query' => 'Potentially unsafe keys removed from query string parameters (GET): %s', |
|
| 47 |
'request' => 'Potentially unsafe keys removed from request body parameters (POST): %s', |
|
| 48 |
'cookies' => 'Potentially unsafe keys removed from cookie parameters: %s', |
|
| 49 |
]; |
|
| 50 |
foreach ($bags as $bag => $message) {
|
|
| 51 |
if (static::processParameterBag($request->$bag, $whitelist, $log_sanitized_keys, $bag, $message)) {
|
|
| 52 |
$update_globals = TRUE; |
|
| 53 |
} |
|
| 47 | 54 |
} |
| 48 |
|
|
| 49 |
// Request body parameters. |
|
| 50 |
$post_sanitized_keys = []; |
|
| 51 |
$request->request->replace(static::stripDangerousValues($request->request->all(), $whitelist, $post_sanitized_keys)); |
|
| 52 |
if ($log_sanitized_keys && !empty($post_sanitized_keys)) {
|
|
| 53 |
trigger_error(sprintf('Potentially unsafe keys removed from request body parameters (POST): %s', implode(', ', $post_sanitized_keys)));
|
|
| 54 |
} |
|
| 55 |
|
|
| 56 |
// Cookie parameters. |
|
| 57 |
$cookie_sanitized_keys = []; |
|
| 58 |
$request->cookies->replace(static::stripDangerousValues($request->cookies->all(), $whitelist, $cookie_sanitized_keys)); |
|
| 59 |
if ($log_sanitized_keys && !empty($cookie_sanitized_keys)) {
|
|
| 60 |
trigger_error(sprintf('Potentially unsafe keys removed from cookie parameters: %s', implode(', ', $cookie_sanitized_keys)));
|
|
| 61 |
} |
|
| 62 |
|
|
| 63 |
if (!empty($get_sanitized_keys) || !empty($post_sanitized_keys) || !empty($cookie_sanitized_keys)) {
|
|
| 55 |
if ($update_globals) {
|
|
| 64 | 56 |
$request->overrideGlobals(); |
| 65 | 57 |
} |
| 66 | 58 |
$request->attributes->set(self::SANITIZED, TRUE); |
| ... | ... | |
| 69 | 61 |
} |
| 70 | 62 |
|
| 71 | 63 |
/** |
| 64 |
* Processes a request parameter bag. |
|
| 65 |
* |
|
| 66 |
* @param \Symfony\Component\HttpFoundation\ParameterBag $bag |
|
| 67 |
* The parameter bag to process. |
|
| 68 |
* @param string[] $whitelist |
|
| 69 |
* An array of keys to whitelist as safe. |
|
| 70 |
* @param bool $log_sanitized_keys |
|
| 71 |
* Set to TRUE to log keys that are sanitized. |
|
| 72 |
* @param string $bag_name |
|
| 73 |
* The request parameter bag name. Either 'query', 'request' or 'cookies'. |
|
| 74 |
* @param string $message |
|
| 75 |
* The message to log if the parameter bag contains keys that are removed. |
|
| 76 |
* If the message contains %s that is replaced by a list of removed keys. |
|
| 77 |
* |
|
| 78 |
* @return bool |
|
| 79 |
* TRUE if the parameter bag has been sanitized, FALSE if not. |
|
| 80 |
*/ |
|
| 81 |
protected static function processParameterBag(ParameterBag $bag, $whitelist, $log_sanitized_keys, $bag_name, $message) {
|
|
| 82 |
$sanitized = FALSE; |
|
| 83 |
$sanitized_keys = []; |
|
| 84 |
$bag->replace(static::stripDangerousValues($bag->all(), $whitelist, $sanitized_keys)); |
|
| 85 |
if (!empty($sanitized_keys)) {
|
|
| 86 |
$sanitized = TRUE; |
|
| 87 |
if ($log_sanitized_keys) {
|
|
| 88 |
trigger_error(sprintf($message, implode(', ', $sanitized_keys)));
|
|
| 89 |
} |
|
| 90 |
} |
|
| 91 |
|
|
| 92 |
if ($bag->has('destination')) {
|
|
| 93 |
$destination_dangerous_keys = static::checkDestination($bag->get('destination'), $whitelist);
|
|
| 94 |
if (!empty($destination_dangerous_keys)) {
|
|
| 95 |
// The destination is removed rather than sanitized because the URL |
|
| 96 |
// generator service is not available and this method is called very |
|
| 97 |
// early in the bootstrap. |
|
| 98 |
$bag->remove('destination');
|
|
| 99 |
$sanitized = TRUE; |
|
| 100 |
if ($log_sanitized_keys) {
|
|
| 101 |
trigger_error(sprintf('Potentially unsafe destination removed from %s parameter bag because it contained the following keys: %s', $bag_name, implode(', ', $destination_dangerous_keys)));
|
|
| 102 |
} |
|
| 103 |
} |
|
| 104 |
} |
|
| 105 |
return $sanitized; |
|
| 106 |
} |
|
| 107 |
|
|
| 108 |
/** |
|
| 109 |
* Checks a destination string to see if it is dangerous. |
|
| 110 |
* |
|
| 111 |
* @param string $destination |
|
| 112 |
* The destination string to check. |
|
| 113 |
* @param array $whitelist |
|
| 114 |
* An array of keys to whitelist as safe. |
|
| 115 |
* |
|
| 116 |
* @return array |
|
| 117 |
* The dangerous keys found in the destination parameter. |
|
| 118 |
*/ |
|
| 119 |
protected static function checkDestination($destination, array $whitelist) {
|
|
| 120 |
$dangerous_keys = []; |
|
| 121 |
$parts = UrlHelper::parse($destination); |
|
| 122 |
// If there is a query string, check its query parameters. |
|
| 123 |
if (!empty($parts['query'])) {
|
|
| 124 |
static::stripDangerousValues($parts['query'], $whitelist, $dangerous_keys); |
|
| 125 |
} |
|
| 126 |
return $dangerous_keys; |
|
| 127 |
} |
|
| 128 |
|
|
| 129 |
/** |
|
| 72 | 130 |
* Strips dangerous keys from $input. |
| 73 | 131 |
* |
| 74 | 132 |
* @param mixed $input |
Also available in: Unified diff