per SA-CORE-2009-007

The forum module does not check the incoming tid:

It appears that the forum module allows malicious HTML. Example:

http://drupal.org/?q=forum/pipes%22%3E%3Ch1%3Emalicious%20html%3Ctable

D6 patch was:

Index: modules/forum/forum.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.pages.inc,v
retrieving revision 1.2
diff -u -p -r1.2 forum.pages.inc
--- modules/forum/forum.pages.inc	26 Jul 2007 06:48:03 -0000	1.2
+++ modules/forum/forum.pages.inc	16 May 2009 16:53:33 -0000
@@ -10,6 +10,11 @@
  * Menu callback; prints a forum listing.
  */
 function forum_page($tid = 0) {
+  if (!is_numeric($tid)) {
+    return MENU_NOT_FOUND;
+  }
+  $tid = (int)$tid;
+
   $topics = '';
   $forum_per_page = variable_get('forum_per_page', 25);
   $sortby = variable_get('forum_order', 1);

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Anonymous’s picture

Anonymous’s picture

Status: Patch (to be ported) » Needs review

I always forget to change the status.

Michelle’s picture

There's another issue out there somewhere for making this not only check that it's numeric but also check that the number is actually a forum term so you don't get wierd results by passing TIDs from non forum terms. I don't know if that can be added here or has to be seperate from this security patch but thought I'd mention it as long as you're patching that bit. :)

Michelle

kjy07’s picture

FileSize
793 bytes

Attached patch includes check to verify the provided term is valid.

Status: Needs review » Needs work

The last submitted patch failed testing.

alexanderpas’s picture

I think we should just commit the patch in #1, and put the other part in a follow-up, as in the current state, it severely changes behaviour of that function (in case of a 0).

kjy07’s picture

The conditional statement in #4 won't allow zero values for $tid to pass. It will display the Forum overview or no Forums defined message (whichever is appropriate), rather than returning MENU_NOT_FOUND.

Status: Needs work » Needs review
Issue tags: -Security Advisory follow-up

brianV requested that failed test be re-tested.

Status: Needs review » Needs work
Issue tags: +Security Advisory follow-up

The last submitted patch failed testing.

brianV’s picture

Status: Needs work » Needs review
FileSize
967 bytes

Attached patch uses filter_var() to validate that $tid is an integer greater than or equal to 0. Furthermore, it checks to make sure it's a valid taxonomy term in the forum vocabulary.

brianV’s picture

Err, now with whitespace fixes.

Status: Needs review » Needs work

The last submitted patch failed testing.

brianV’s picture

Status: Needs work » Needs review
FileSize
963 bytes

Status: Needs review » Needs work

The last submitted patch failed testing.

brianV’s picture

Status: Needs work » Needs review
FileSize
993 bytes

Status: Needs review » Needs work

The last submitted patch failed testing.

brianV’s picture

Status: Needs work » Needs review
FileSize
755 bytes

Final pass.

I removed the checks ensuring that the taxonomy term is valid and is a forum term as I decided to rethink where they should be implemented. I will be opening a separate issue for that.

This final patch accomplishes only what is needed to fix this issue - that is, the security issue.

webchick’s picture

Could someone please take a look at this so we can ship alpha 1 with no known security holes? :)

Damien Tournoud’s picture

I suggest we fix that properly.

The real issue is that the forum module is using menu loaders improperly. Here is a minimal fix.

Damien Tournoud’s picture

By the way, properly using menu loaders also fixes #221860: 404 pages and containers.

brianV’s picture

Looks good to me, but I will wait for someone else to verify the fix as well since it's a security issue.

Are going to want to re-backport this fix to D6 after?

greggles’s picture

Status: Needs review » Needs work

It seems there is an incomplete docblock in the comments for forum_forum_load? It looks like you were going to define the keys in the array and then forgot.

I tried to confirm that this patch fixes the original security bug, but I can no longer directly reproduce that bug.

Steps to repeat:
1. Install core
2. Create a container
3. Create a forum inside that container
4. Post a node into that forum from step 3
5. Visit http://7d.local/forum/pipes%22%3E%3Ch1%3Emalicious%20html%3Ctable

Expected results:
The <1>malicious html<table would be injected into the page as html.

Actual results:
They aren't included as HTML, though I do get a "No forums defined" message which DamZ is right makes less sense than a 404.

After applying the patch and rebuilding the cache I get a 404 which feels more appropriate and is a performance improvement (since requests for invalid pages should do as little work as possible and 404 pages are relatively lightweight).

In summary: I think the security issue has been fixed already elsewhere, but the current patch in #19 is an improvement to core.

Needs work for the documentation.

sun.core’s picture

Status: Needs work » Needs review
grendzy’s picture

Status: Needs review » Needs work
+++ modules/forum/forum.module
@@ -715,17 +722,40 @@ function forum_url_outbound_alter(&$path, &$options, $original_path) {
  * @return
- *   Array of object containing the forum information.
+ *   Array of object containing the forum information, with the following keys:
+ *    - 
  */

patch looks good, but I agree the docblock is incomplete. The return value now looks something like
tid (String)
vid (String)
name (String)
description (String)
format (String)
weight (String)
vocabulary_machine_name (String)
rdf_mapping (Array)
parents (Array)
forums (Array)

Powered by Dreditor.

greggles’s picture

Status: Needs work » Needs review
FileSize
5.73 KB

Ok, here is a re-roll with that included in the docblock and to fix some offsets.

grendzy’s picture

Status: Needs review » Reviewed & tested by the community

Applies cleanly. Confirmed this is the same fix as #19 plus the corrected docblock.

Dries’s picture

This looks good, although the code in forum_forum_load() could use some additional code comments. Care to try and add some?

aspilicious’s picture

Status: Reviewed & tested by the community » Needs work

Putting to needs work, please add some comments so we can clean up the issue queue.

mr.baileys’s picture

Priority: Critical » Normal
Issue tags: -Security Advisory follow-up, -webchick's D7 alpha hit list

Downgrading to normal and removing tags.

mr.baileys’s picture

Priority: Normal » Critical
Issue tags: +Security Advisory follow-up, +webchick's D7 alpha hit list

Whoops, sorry, thought this was commited and set to needs work for comments only...

grendzy’s picture

Status: Needs work » Needs review
FileSize
6.75 KB

Revised patch with code comments, and correct docblock. Functionally equivalent to #19.

Status: Needs review » Needs work

The last submitted patch, 520736.patch, failed testing.

grendzy’s picture

Status: Needs work » Needs review
FileSize
6.72 KB

whoops, forgot to remove the git prefix.

pwolanin’s picture

code style problem:

+  return $cache[$tid] = $forum_term;;

remove extra ; and usually we don't have assignment and return on the same line.

grendzy’s picture

FileSize
6.76 KB

good catch.

dmitrig01’s picture

+++ modules/forum/forum.module
@@ -719,27 +726,51 @@ function forum_form($node, $form_state) {
+ *    -num_topics Number of topics in the forum
+ *    -num_posts Total number of posts in all topics
+ *    -last_post Most recent post for the forum
+ *    -forums An array of child forums

Space between - and the key please. And add single quotes.

+++ modules/forum/forum.module
@@ -91,6 +91,14 @@ function forum_menu() {
+    'page arguments' => array(),

Unneeded

+++ modules/forum/forum.module
@@ -719,27 +726,51 @@ function forum_form($node, $form_state) {
+ *    -num_topics Number of topics in the forum
+ *    -num_posts Total number of posts in all topics
+ *    -last_post Most recent post for the forum
+ *    -forums An array of child forums

Space between '-' and the key please. And add single quotes.

Other than that, looks good.

dmitrig01’s picture

Status: Needs review » Needs work
pwolanin’s picture

this is a bit inconsistent:

-function forum_get_forums($tid = 0) {
+function forum_forum_load($tid) {
   $cache = &drupal_static(__FUNCTION__, array());
 
+  // Return a cached forum tree if available.
   if (isset($cache[$tid])) {
     return $cache[$tid];
   }
 
-  $forums = array();
   $vid = variable_get('forum_nav_vocabulary', 0);
+
+  // Load and validate the parent term.
+  if ($tid) {
+    $forum_term = taxonomy_term_load($tid);
+    if (!$forum_term || ($forum_term->vid != $vid)) {
+      return $cache[$tid] = FALSE;
+    }
+  }
+  // If $tid is 0, create an empty object to hold the child terms.
+  else if ($tid === 0) {
+    $forum_term = (object) array(
+      'tid' => 0,
+    );
+  }

versus:

+function forum_page($forum_term = NULL) {
+  if (!isset($forum_term)) {
+    // On the main page, display all the top-level forums.
+    $forum_term = forum_forum_load(0);
+  }
grendzy’s picture

Status: Needs work » Needs review
FileSize
6.88 KB

incorporating feedback from dmitrig01 and pwolanin.

Status: Needs review » Needs work

The last submitted patch, 520736.patch, failed testing.

grendzy’s picture

Status: Needs work » Needs review
FileSize
6.85 KB
catch’s picture

+++ modules/forum/forum.module
@@ -719,27 +725,54 @@ function forum_form($node, $form_state) {
+  if (is_null($tid)) {
+    $tid = 0;
+  }

This should be !isset().

Otherwise looks good.

104 critical left. Go review some!

grendzy’s picture

FileSize
6.85 KB

changed to !isset().

catch’s picture

Status: Needs review » Reviewed & tested by the community

Looks great.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

The amount of code being changed here makes me go "EEEEE!" and think we probably need tests for this. But I talked it over with catch. It would be odd to test just one menu router path's security and not all of them, and it would also be odd to test that a function which only accepts an int as valid input only accepts an int as valid input... and we're not likely to break this again.

So therefore, committed to HEAD. Thanks a lot for your work on this folks! Great to see the number of known security holes coming down.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

andypost’s picture

This fix leads to unavailability to fix #148145: "Forums" title is not localized
Because user can only rename /forum menu item and not /forum/%