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

View differences:

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