Security update to Drupal 8.4.6
[yaffs-website] / web / core / lib / Drupal / Core / Security / RequestSanitizer.php
1 <?php
2
3 namespace Drupal\Core\Security;
4
5 use Symfony\Component\HttpFoundation\Request;
6
7 /**
8  * Sanitizes user input.
9  */
10 class RequestSanitizer {
11
12   /**
13    * Request attribute to mark the request as sanitized.
14    */
15   const SANITIZED = '_drupal_request_sanitized';
16
17   /**
18    * The name of the setting that configures the whitelist.
19    */
20   const SANITIZE_WHITELIST = 'sanitize_input_whitelist';
21
22   /**
23    * The name of the setting that determines if sanitized keys are logged.
24    */
25   const SANITIZE_LOG = 'sanitize_input_logging';
26
27   /**
28    * Strips dangerous keys from user input.
29    *
30    * @param \Symfony\Component\HttpFoundation\Request $request
31    *   The incoming request to sanitize.
32    * @param string[] $whitelist
33    *   An array of keys to whitelist as safe. See default.settings.php.
34    * @param bool $log_sanitized_keys
35    *   (optional) Set to TRUE to log an keys that are sanitized.
36    *
37    * @return \Symfony\Component\HttpFoundation\Request
38    *   The sanitized request.
39    */
40   public static function sanitize(Request $request, $whitelist, $log_sanitized_keys = FALSE) {
41     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)));
47       }
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)) {
64         $request->overrideGlobals();
65       }
66       $request->attributes->set(self::SANITIZED, TRUE);
67     }
68     return $request;
69   }
70
71   /**
72    * Strips dangerous keys from $input.
73    *
74    * @param mixed $input
75    *   The input to sanitize.
76    * @param string[] $whitelist
77    *   An array of keys to whitelist as safe.
78    * @param string[] $sanitized_keys
79    *   An array of keys that have been removed.
80    *
81    * @return mixed
82    *   The sanitized input.
83    */
84   protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
85     if (is_array($input)) {
86       foreach ($input as $key => $value) {
87         if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
88           unset($input[$key]);
89           $sanitized_keys[] = $key;
90         }
91         else {
92           $input[$key] = static::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
93         }
94       }
95     }
96     return $input;
97   }
98
99 }