Index: includes/coder_security.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/coder/includes/coder_security.inc,v retrieving revision 1.15.2.17 diff -u -u -p -r1.15.2.17 coder_security.inc --- includes/coder_security.inc 27 Sep 2008 16:59:30 -0000 1.15.2.17 +++ includes/coder_security.inc 29 Sep 2008 13:09:07 -0000 @@ -50,6 +50,13 @@ function coder_security_reviews() { '#source' => 'quote', '#warning_callback' => '_coder_6x_unquoted_sql_placeholders', ), + array( + '#type' => 'regex', + '#value' => '.*[\'"]SELECT\s+.*\s+FROM\s+\{node\}', + '#never' => '[\s\(]db_rewrite_sql\s*\(', + '#source' => 'allphp', + '#warning_callback' => '_coder_security_db_rewrite_sql', + ) ); $review = array( '#title' => 'Drupal Security Checks', @@ -111,3 +118,13 @@ function _coder_6x_unquoted_sql_placehol '#warning' => t('SQL query handling data in a potentially insecure way by using the %%s placeholder without wrapping it in single quotes. This is a potential source of SQL injection attacks when the value can come from user data.'), ); } + +function _coder_security_db_rewrite_sql() { + return array( + '#warning' => t('"SELECT FROM {node}" statements should probably be wrapped in !db_rewrite_sql', + array( + '!db_rewrite_sql' => theme('drupalapi', 'db_rewrite_sql'), + ) + ), + ); +} 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 -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 29 Sep 2008 13:09:07 -0000 @@ -26,11 +26,11 @@ class CoderSecurityTest extends CoderTes } function testSecuritySQLVariableInjection() { - $this->assertCoderFail(' $results = db_query("SELECT * FROM {node} WHERE nid=$nid");'); + $this->assertCoderFail(' $results = db_query("SELECT * FROM {node_revisions} WHERE nid=$nid");'); $this->assertCoderPass(' $results = db_query("SELECT * FROM {false_accounts} WHERE uids REGEXP \'^%s,|,%s,|,%s$\'");'); - $this->assertCoderPass(' $results = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=\'%s\' AND (r.title REGEXP \'^[^[:alpha:]].*$\')");'); - $this->assertCoderFail(' $results = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=\'%s\' AND (r.title REGEXP \'^[^[:alpha:]].*$\') AND nid=$nid");'); - $this->assertCoderFail(' $results = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=$type AND (r.title REGEXP \'^[^[:alpha:]].*$\')");'); + $this->assertCoderPass(' $results = db_query(db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=\'%s\' AND (r.title REGEXP \'^[^[:alpha:]].*$\')"));'); + $this->assertCoderFail(' $results = db_query(db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=\'%s\' AND (r.title REGEXP \'^[^[:alpha:]].*$\') AND nid=$nid"));'); + $this->assertCoderFail(' $results = db_query(db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {node_revisions} r USING (nid, vid) WHERE n.type=$type AND (r.title REGEXP \'^[^[:alpha:]].*$\')"));'); $this->assertCoderFail(' $results = db_query("SELECT * FROM {foo} WHERE name=$name");'); $this->assertCoderFail(' db_query("INSERT INTO {foo} SET name=\'$name\'");'); $this->assertCoderFail(' $sql = "INSERT INTO {foo} SET name=\'$name\'";'); @@ -52,4 +52,9 @@ class CoderSecurityTest extends CoderTes $this->assertCoderPass(' $sql = "INSERT INTO {foo} (1,%d)";'); $this->assertCoderPass(' $sql = "INSERT INTO {foo} (1, %d)";'); } + + function testSecurityDbRewrite() { + $this->assertCoderFail(' $results = db_query("SELECT * FROM {node}");'); + $this->assertCoderPass(' $results = db_query(db_rewrite_sql("SELECT * FROM {node}"));'); + } }