Project

General

Profile

Paste
Download (4.05 KB) Statistics
| Branch: | Revision:

root / drupal7 / includes / request-sanitizer.inc @ 6d8023f2

1
<?php
2

    
3
/**
4
 * @file
5
 * Contains code for sanitizing user input from the request.
6
 */
7

    
8
/**
9
 * Sanitizes user input from the request.
10
 */
11
class DrupalRequestSanitizer {
12

    
13
  /**
14
   * Tracks whether the request was already sanitized.
15
   */
16
  protected static $sanitized = FALSE;
17

    
18
  /**
19
   * Modifies the request to strip dangerous keys from user input.
20
   */
21
  public static function sanitize() {
22
    if (!self::$sanitized) {
23
      $whitelist = variable_get('sanitize_input_whitelist', array());
24
      $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
25

    
26
      // Process query string parameters.
27
      $get_sanitized_keys = array();
28
      $_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
29
      if ($log_sanitized_keys && $get_sanitized_keys) {
30
        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
31
      }
32

    
33
      // Process request body parameters.
34
      $post_sanitized_keys = array();
35
      $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
36
      if ($log_sanitized_keys && $post_sanitized_keys) {
37
        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
38
      }
39

    
40
      // Process cookie parameters.
41
      $cookie_sanitized_keys = array();
42
      $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
43
      if ($log_sanitized_keys && $cookie_sanitized_keys) {
44
        _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
45
      }
46

    
47
      $request_sanitized_keys = array();
48
      $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
49

    
50
      self::$sanitized = TRUE;
51
    }
52
  }
53

    
54
  /**
55
   * Removes the destination if it is dangerous.
56
   *
57
   * Note this can only be called after common.inc has been included.
58
   *
59
   * @return bool
60
   *   TRUE if the destination has been removed from $_GET, FALSE if not.
61
   */
62
  public static function cleanDestination() {
63
    $dangerous_keys = array();
64
    $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
65

    
66
    $parts = drupal_parse_url($_GET['destination']);
67
    // If there is a query string, check its query parameters.
68
    if (!empty($parts['query'])) {
69
      $whitelist = variable_get('sanitize_input_whitelist', array());
70

    
71
      self::stripDangerousValues($parts['query'], $whitelist, $dangerous_keys);
72
      if (!empty($dangerous_keys)) {
73
        // The destination is removed rather than sanitized to mirror the
74
        // handling of external destinations.
75
        unset($_GET['destination']);
76
        unset($_REQUEST['destination']);
77
        if ($log_sanitized_keys) {
78
          trigger_error(format_string('Potentially unsafe destination removed from query string parameters (GET) because it contained the following keys: @keys', array('@keys' => implode(', ', $dangerous_keys))));
79
        }
80
        return TRUE;
81
      }
82
    }
83
    return FALSE;
84
  }
85

    
86
  /**
87
   * Strips dangerous keys from the provided input.
88
   *
89
   * @param mixed $input
90
   *   The input to sanitize.
91
   * @param string[] $whitelist
92
   *   An array of keys to whitelist as safe.
93
   * @param string[] $sanitized_keys
94
   *   An array of keys that have been removed.
95
   *
96
   * @return mixed
97
   *   The sanitized input.
98
   */
99
  protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
100
    if (is_array($input)) {
101
      foreach ($input as $key => $value) {
102
        if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
103
          unset($input[$key]);
104
          $sanitized_keys[] = $key;
105
        }
106
        else {
107
          $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
108
        }
109
      }
110
    }
111
    return $input;
112
  }
113

    
114
}