Index: includes/coder_security.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/coder/includes/coder_security.inc,v retrieving revision 1.15.2.17.2.1 diff -u -p -r1.15.2.17.2.1 coder_security.inc --- includes/coder_security.inc 29 Sep 2008 13:12:32 -0000 1.15.2.17.2.1 +++ includes/coder_security.inc 12 Nov 2008 00:23:25 -0000 @@ -16,6 +16,20 @@ function coder_security_reviews() { $rules = array( array( '#type' => 'regex', + '#value' => 'drupal_set_title\(.*\$', + '#never' => 'drupal_set_title\(t\(.*?array\(.*$', + '#source' => 'allphp', + '#warning_callback' => '_coder_security_drupal_set_title_filter_warning', + ), + array( + '#type' => 'regex', + '#value' => 'drupal_set_message\(.*\$', + '#never' => 'drupal_set_message\(t\(.*?array\(.*$', + '#source' => 'allphp', + '#warning_callback' => '_coder_security_drupal_set_message_filter_warning', + ), + array( + '#type' => 'regex', '#value' => 'l\(check_plain\(.*', '#never' => '[\'"]html[\'"]\s*=>\s*(TRUE|1)', '#source' => 'allphp', @@ -77,6 +91,26 @@ function coder_security_reviews() { * Define the warning callbacks. */ +function _coder_security_drupal_set_title_filter_warning() { + return t('!drupal_set_title() only accepts filtered text, be sure to use !check_plain() or !filter_xss_admin() or similar.', + array( + '!drupal_set_title' => theme('drupalapi', 'drupal_set_title'), + '!check_plain' => theme('drupalapi', 'check_plain'), + '!filter_xss_admin' => theme('drupalapi', 'filter_xss_admin'), + ) + ); +} + +function _coder_security_drupal_set_message_filter_warning() { + return t('!drupal_set_message() only accepts filtered text, be sure to use !check_plain() or !filter_xss_admin() or similar.', + array( + '!drupal_set_message' => theme('drupalapi', 'drupal_set_message'), + '!check_plain' => theme('drupalapi', 'check_plain'), + '!filter_xss_admin' => theme('drupalapi', 'filter_xss_admin'), + ) + ); +} + function _coder_security_l_check_plain_warning() { return t('!l() already contains a !check_plain() call by default', array( Index: tests/coder_security.test =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/coder/tests/Attic/coder_security.test,v retrieving revision 1.1.2.8 diff -u -p -r1.1.2.8 coder_security.test --- tests/coder_security.test 27 Sep 2008 16:59:57 -0000 1.1.2.8 +++ tests/coder_security.test 12 Nov 2008 00:23:25 -0000 @@ -5,7 +5,7 @@ class CoderSecurityTest extends CoderTes function __construct($id = NULL) { parent::__construct('security', $id); } - + function getInfo() { return array( 'name' => t('Coder Security Tests'), @@ -13,7 +13,7 @@ class CoderSecurityTest extends CoderTes 'group' => t('Coder'), ); } - + function testSecurityCheckPlain() { $this->assertCoderFail('$var = l(check_plain($input), "path/to/drupal");'); $this->assertCoderFail('$var = l(check_plain($input), "path/to/drupal", array("html" => FALSE);'); @@ -52,4 +52,12 @@ class CoderSecurityTest extends CoderTes $this->assertCoderPass(' $sql = "INSERT INTO {foo} (1,%d)";'); $this->assertCoderPass(' $sql = "INSERT INTO {foo} (1, %d)";'); } + + function testDrupalSetMessageTitle() { + $this->assertCoderPass(' drupal_set_message(t("Here is some @safe_data", array("@safe_data" => $tainted_data));'); + $this->assertCoderFail(' drupal_set_message($tainted_data);'); + $this->assertCoderFail(' drupal_set_message("Here is some ". $tainted_data);'); + $this->assertCoderFail(' drupal_set_message("Here is some $tainted_data");'); + $this->assertCoderFail(' drupal_set_message(t("Here is some ". $tainted_data));'); + } }