comparison core/lib/Drupal/Core/Security/RequestSanitizer.php @ 15:e200cb7efeb3

Update Drupal core to 8.5.3 via Composer
author Chris Cannam
date Thu, 26 Apr 2018 11:26:54 +0100
parents 5fb285c0d0e3
children c2387f117808
comparison
equal deleted inserted replaced
14:1fec387a4317 15:e200cb7efeb3
1 <?php 1 <?php
2 2
3 namespace Drupal\Core\Security; 3 namespace Drupal\Core\Security;
4 4
5 use Drupal\Component\Utility\UrlHelper;
6 use Symfony\Component\HttpFoundation\ParameterBag;
5 use Symfony\Component\HttpFoundation\Request; 7 use Symfony\Component\HttpFoundation\Request;
6 8
7 /** 9 /**
8 * Sanitizes user input. 10 * Sanitizes user input.
9 */ 11 */
37 * @return \Symfony\Component\HttpFoundation\Request 39 * @return \Symfony\Component\HttpFoundation\Request
38 * The sanitized request. 40 * The sanitized request.
39 */ 41 */
40 public static function sanitize(Request $request, $whitelist, $log_sanitized_keys = FALSE) { 42 public static function sanitize(Request $request, $whitelist, $log_sanitized_keys = FALSE) {
41 if (!$request->attributes->get(self::SANITIZED, FALSE)) { 43 if (!$request->attributes->get(self::SANITIZED, FALSE)) {
42 // Process query string parameters. 44 $update_globals = FALSE;
43 $get_sanitized_keys = []; 45 $bags = [
44 $request->query->replace(static::stripDangerousValues($request->query->all(), $whitelist, $get_sanitized_keys)); 46 'query' => 'Potentially unsafe keys removed from query string parameters (GET): %s',
45 if ($log_sanitized_keys && !empty($get_sanitized_keys)) { 47 'request' => 'Potentially unsafe keys removed from request body parameters (POST): %s',
46 trigger_error(sprintf('Potentially unsafe keys removed from query string parameters (GET): %s', implode(', ', $get_sanitized_keys))); 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 55 if ($update_globals) {
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(); 56 $request->overrideGlobals();
65 } 57 }
66 $request->attributes->set(self::SANITIZED, TRUE); 58 $request->attributes->set(self::SANITIZED, TRUE);
67 } 59 }
68 return $request; 60 return $request;
61 }
62
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;
69 } 127 }
70 128
71 /** 129 /**
72 * Strips dangerous keys from $input. 130 * Strips dangerous keys from $input.
73 * 131 *