Skip to content

Update to Pressflow 6.38#1

Merged
Muppetteer merged 3 commits intoMuppetteer:masterfrom
pressflow:master
Mar 2, 2016
Merged

Update to Pressflow 6.38#1
Muppetteer merged 3 commits intoMuppetteer:masterfrom
pressflow:master

Conversation

@Muppetteer
Copy link
Copy Markdown
Owner

No description provided.

M Parker and others added 3 commits February 24, 2016 16:25
Note there were conflicts in `CHANGELOG.txt` and `includes/common.inc`,
that were easy to merge, however, one conflict in drupal_set_header()
(in modules/system/system.module) was not, and I had to write custom
code for it.

Essentially drupal_set_header() had been moved from
`includes/common.inc` into `includes/bootstrap.inc`, and the two
functions had diverged somewhat since the move. Looking at the Pressflow
code, it appeared to be vulnerable to the same attack that was patched
in Drupal core 6.38 (HTTP header injection using line breaks on PHP
versions earlier than 5.1.2).

In Drupal core, the patch was:

```
diff --git a/includes/common.inc b/includes/common.inc
index 19798ba..9a28c06 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -150,8 +154,15 @@ function drupal_set_header($header = NULL) {
   static $stored_headers = array();

   if (strlen($header)) {
-    header($header);
-    $stored_headers[] = $header;
+    // Protect against header injection attacks if PHP is too old to do that.
+    if (version_compare(PHP_VERSION, '5.1.2', '<') && (strpos($header, "\n") !== FALSE || strpos($header, "\r") !== FALSE)) {
+      // Use the same warning message that newer versions of PHP use.
+      trigger_error('Header may not contain more than a single header, new line detected', E_USER_WARNING);
+    }
+    else {
+      header($header);
+      $stored_headers[] = $header;
+    }
   }
   return implode("\n", $stored_headers);
 }
```

- see http://cgit.drupalcode.org/drupal/commit/?h=6.38&id=18f1c229fcb87b1a1f94fcb1f0785ba3d40fc402

Pressflow constructs headers differently though: it constructs a
`$headers` array, where it maps `$name_lower` (i.e.: the properly-cased
HTTP header name) to `$value` (i.e.: the value of that header). It then
passes the `$headers` array to `drupal_send_headers()`.

So in this patch, I added the check around the code which modifies the
`$headers` array:

```
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 58b74a6..e50053b 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -835,17 +835,32 @@ function drupal_set_header($name = NULL, $value = NULL, $append = FALSE) {
   }
   _drupal_set_preferred_header_name($name);

-  if (!isset($value)) {
-    $headers[$name_lower] = FALSE;
-  }
-  elseif (isset($headers[$name_lower]) && $append) {
-    // Multiple headers with identical names may be combined using comma (RFC
-    // 2616, section 4.2).
-    $headers[$name_lower] .= ',' . $value;
+  // Protect against header injection attacks if PHP is too old to do that.
+  // See https://www.drupal.org/SA-CORE-2016-001, and
+  // https://www.drupal.org/drupal-6.38-release-notes
+  if (version_compare(PHP_VERSION, '5.1.2', '<') &&
+    (
+      (strpos($name_lower, "\n") !== FALSE || strpos($name_lower, "\r") !== FALSE) ||
+      (strpos($value, "\n") !== FALSE || strpos($value, "\r") !== FALSE)
+    )
+  ) {
+    // Use the same warning message that newer versions of PHP use.
+    trigger_error('Header may not contain more than a single header, new line detected', E_USER_WARNING);
   }
   else {
-    $headers[$name_lower] = $value;
+    if (!isset($value)) {
+      $headers[$name_lower] = FALSE;
+    }
+    elseif (isset($headers[$name_lower]) && $append) {
+      // Multiple headers with identical names may be combined using comma (RFC
+      // 2616, section 4.2).
+      $headers[$name_lower] .= ',' . $value;
+    }
+    else {
+      $headers[$name_lower] = $value;
+    }
   }
+
   drupal_send_headers(array($name => $headers[$name_lower]), TRUE);
 }
```

I would very much appreciate some code review and testing. It's been a
while since I've worked with Drupal 6 code and Drupal 6 sites!
Muppetteer added a commit that referenced this pull request Mar 2, 2016
Update to Pressflow 6.38
@Muppetteer Muppetteer merged commit 3600028 into Muppetteer:master Mar 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant