Last active
March 28, 2018 19:47
-
-
Save attila/8f7fb4854ad891f646b1e034c05665b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc | |
index 0428bd3..1814aa8 100644 | |
--- a/includes/bootstrap.inc | |
+++ b/includes/bootstrap.inc | |
@@ -2360,6 +2360,10 @@ function _drupal_bootstrap_configuration() { | |
timer_start('page'); | |
// Initialize the configuration, including variables from settings.php. | |
drupal_settings_initialize(); | |
+ | |
+ // Sanitize unsafe keys from the request. | |
+ require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc'; | |
+ DrupalRequestSanitizer::sanitize(); | |
} | |
/** | |
@@ -3570,3 +3574,38 @@ function drupal_clear_opcode_cache($filepath) { | |
@apc_delete_file($filepath); | |
} | |
} | |
+ | |
+/** | |
+ * Invokes trigger_error() with logging delayed until the end of the request. | |
+ * | |
+ * This is an alternative to PHP's trigger_error() function which can be used | |
+ * during low-level Drupal core operations that need to avoid being interrupted | |
+ * by a watchdog() call. | |
+ * | |
+ * Normally, Drupal's error handler calls watchdog() in response to a | |
+ * trigger_error() call. However, this invokes hook_watchdog() which can run | |
+ * arbitrary code. If the trigger_error() happens in the middle of an | |
+ * operation such as a rebuild operation which should not be interrupted by | |
+ * arbitrary code, that could potentially break or trigger the rebuild again. | |
+ * This function protects against that by delaying the watchdog() call until | |
+ * the end of the current page request. | |
+ * | |
+ * This is an internal function which should only be called by low-level Drupal | |
+ * core functions. It may be removed in a future Drupal 7 release. | |
+ * | |
+ * @param string $error_msg | |
+ * The error message to trigger. As with trigger_error() itself, this is | |
+ * limited to 1024 bytes; additional characters beyond that will be removed. | |
+ * @param int $error_type | |
+ * (optional) The type of error. This should be one of the E_USER family of | |
+ * constants. As with trigger_error() itself, this defaults to E_USER_NOTICE | |
+ * if not provided. | |
+ * | |
+ * @see _drupal_log_error() | |
+ */ | |
+function _drupal_trigger_error_with_delayed_logging($error_msg, $error_type = E_USER_NOTICE) { | |
+ $delay_logging = &drupal_static(__FUNCTION__, FALSE); | |
+ $delay_logging = TRUE; | |
+ trigger_error($error_msg, $error_type); | |
+ $delay_logging = FALSE; | |
+} | |
diff --git a/includes/request-sanitizer.inc b/includes/request-sanitizer.inc | |
new file mode 100644 | |
index 0000000..1daa6b5 | |
--- /dev/null | |
+++ b/includes/request-sanitizer.inc | |
@@ -0,0 +1,82 @@ | |
+<?php | |
+ | |
+/** | |
+ * @file | |
+ * Contains code for sanitizing user input from the request. | |
+ */ | |
+ | |
+/** | |
+ * Sanitizes user input from the request. | |
+ */ | |
+class DrupalRequestSanitizer { | |
+ | |
+ /** | |
+ * Tracks whether the request was already sanitized. | |
+ */ | |
+ protected static $sanitized = FALSE; | |
+ | |
+ /** | |
+ * Modifies the request to strip dangerous keys from user input. | |
+ */ | |
+ public static function sanitize() { | |
+ if (!self::$sanitized) { | |
+ $whitelist = variable_get('sanitize_input_whitelist', array()); | |
+ $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE); | |
+ | |
+ // Process query string parameters. | |
+ $get_sanitized_keys = array(); | |
+ $_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys); | |
+ if ($log_sanitized_keys && $get_sanitized_keys) { | |
+ _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); | |
+ } | |
+ | |
+ // Process request body parameters. | |
+ $post_sanitized_keys = array(); | |
+ $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys); | |
+ if ($log_sanitized_keys && $post_sanitized_keys) { | |
+ _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); | |
+ } | |
+ | |
+ // Process cookie parameters. | |
+ $cookie_sanitized_keys = array(); | |
+ $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys); | |
+ if ($log_sanitized_keys && $cookie_sanitized_keys) { | |
+ _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); | |
+ } | |
+ | |
+ $request_sanitized_keys = array(); | |
+ $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys); | |
+ | |
+ self::$sanitized = TRUE; | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * Strips dangerous keys from the provided input. | |
+ * | |
+ * @param mixed $input | |
+ * The input to sanitize. | |
+ * @param string[] $whitelist | |
+ * An array of keys to whitelist as safe. | |
+ * @param string[] $sanitized_keys | |
+ * An array of keys that have been removed. | |
+ * | |
+ * @return mixed | |
+ * The sanitized input. | |
+ */ | |
+ protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) { | |
+ if (is_array($input)) { | |
+ foreach ($input as $key => $value) { | |
+ if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) { | |
+ unset($input[$key]); | |
+ $sanitized_keys[] = $key; | |
+ } | |
+ else { | |
+ $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys); | |
+ } | |
+ } | |
+ } | |
+ return $input; | |
+ } | |
+ | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment