Commit 4b5e3931 authored by dsnopek's avatar dsnopek

Issue #2965601 by catch, dsnopek: [core] Add D6LTS patch for SA-CORE-2018-004

parent f88a81d7
diff --git a/filefield.module b/filefield.module
index 9045c10..fad1746 100644
--- a/filefield.module
+++ b/filefield.module
@@ -590,7 +590,7 @@ function filefield_js($type_name, $field_name, $delta) {
// JSON output.
$GLOBALS['devel_shutdown'] = FALSE;
- if (empty($field) || empty($_POST['form_build_id'])) {
+ if (empty($field) || $field['type'] != 'filefield' || !is_numeric($delta) || empty($_POST['form_build_id'])) {
// Invalid request.
drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
print drupal_to_js(array('data' => theme('status_messages')));
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 5654dde..72343aa 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -1202,6 +1202,10 @@ function _drupal_bootstrap($phase) {
unset($_GET['destination']);
unset($_REQUEST['destination']);
}
+ // Ensure that the destination's query parameters are not dangerous.
+ if (isset($_GET['destination'])) {
+ _drupal_bootstrap_clean_destination();
+ }
// If there's still something in $_REQUEST['destination'] that didn't
// come from $_GET, check it too.
if (isset($_REQUEST['destination']) && (!isset($_GET['destination']) || $_REQUEST['destination'] != $_GET['destination']) && menu_path_is_external($_REQUEST['destination'])) {
@@ -1660,3 +1664,92 @@ function _drupal_bootstrap_sanitize_input(&$input, $whitelist = array()) {
return $sanitized_keys;
}
+
+/**
+ * Removes the destination if it is dangerous.
+ *
+ * Note this can only be called after common.inc has been included.
+ *
+ * @return bool
+ * TRUE if the destination has been removed from $_GET, FALSE if not.
+ */
+function _drupal_bootstrap_clean_destination() {
+ $dangerous_keys = array();
+
+ $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
+
+ $parts = _drupal_parse_url($_GET['destination']);
+ if (!empty($parts['query'])) {
+ $whitelist = variable_get('sanitize_input_whitelist', array());
+ $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
+
+ $dangerous_keys = _drupal_bootstrap_sanitize_input($parts['query'], $whitelist);
+ if (!empty($dangerous_keys)) {
+ // The destination is removed rather than sanitized to mirror the
+ // handling of external destinations.
+ unset($_GET['destination']);
+ unset($_REQUEST['destination']);
+ if ($log_sanitized_keys) {
+ trigger_error(sprintf('Potentially unsafe destination removed from query string parameters (GET) because it contained the following keys: %s', implode(', ', $dangerous_keys)));
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Backport of drupal_parse_url() from Drupal 7.
+ */
+function _drupal_parse_url($url) {
+ $options = array(
+ 'path' => NULL,
+ 'query' => array(),
+ 'fragment' => '',
+ );
+
+ // External URLs: not using parse_url() here, so we do not have to rebuild
+ // the scheme, host, and path without having any use for it.
+ if (strpos($url, '://') !== FALSE) {
+
+ // Split off everything before the query string into 'path'.
+ $parts = explode('?', $url);
+ $options['path'] = $parts[0];
+
+ // If there is a query string, transform it into keyed query parameters.
+ if (isset($parts[1])) {
+ $query_parts = explode('#', $parts[1]);
+ parse_str($query_parts[0], $options['query']);
+
+ // Take over the fragment, if there is any.
+ if (isset($query_parts[1])) {
+ $options['fragment'] = $query_parts[1];
+ }
+ }
+ }
+ else {
+
+ // parse_url() does not support relative URLs, so make it absolute. E.g. the
+ // relative URL "foo/bar:1" isn't properly parsed.
+ $parts = parse_url('http://example.com/' . $url);
+
+ // Strip the leading slash that was just added.
+ $options['path'] = substr($parts['path'], 1);
+ if (isset($parts['query'])) {
+ parse_str($parts['query'], $options['query']);
+ }
+ if (isset($parts['fragment'])) {
+ $options['fragment'] = $parts['fragment'];
+ }
+ }
+
+ // The 'q' parameter contains the path of the current page if clean URLs are
+ // disabled. It overrides the 'path' of the URL when present, even if clean
+ // URLs are enabled, due to how Apache rewriting rules work. The path
+ // parameter must be a string.
+ if (isset($options['query']['q']) && is_string($options['query']['q'])) {
+ $options['path'] = $options['query']['q'];
+ unset($options['query']['q']);
+ }
+ return $options;
+}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment