t('Coder Security Tests'),
'description' => t('Tests for the coder security review.'),
'group' => t('Coder'),
);
}
function testSecurityCheckPlain() {
$this->assertCoderReviewFail('$var = l(check_plain($input), "path/to/drupal");');
$this->assertCoderReviewFail('$var = l(check_plain($input), "path/to/drupal", array("html" => FALSE);');
$this->assertCoderReviewFail('$var = l(check_plain($input), "path/to/drupal", array("html" => $value);');
$this->assertCoderReviewFail('$var = l(check_plain($input), "path/to/drupal", array("html" => 0);');
$this->assertCoderReviewPass('$var = l(check_plain($input), "path/to/drupal", array("html" => TRUE);');
$this->assertCoderReviewPass('$var = l(check_plain($input), "path/to/drupal", array(\'html\' => TRUE);');
$this->assertCoderReviewPass('$var = l(check_plain($input), "path/to/drupal", array("html" => 1);');
$this->assertCoderReviewPass('$var = l(check_plain($input), "path/to/drupal", array(\'html\' => 1);');
}
function testSecuritySQLVariableInjection() {
$this->assertCoderReviewFail(' $results = db_query("SELECT * FROM {node_revisions} WHERE nid=$nid");');
$this->assertCoderReviewPass(' $results = db_query("SELECT * FROM {false_accounts} WHERE uids REGEXP \'^%s,|,%s,|,%s$\'");');
$this->assertCoderReviewPass(' $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->assertCoderReviewPass(' $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->assertCoderReviewFail(' $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->assertCoderReviewFail(' $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->assertCoderReviewFail(' $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->assertCoderReviewFail(' $results = db_query("SELECT * FROM {foo} WHERE name=$name");');
$this->assertCoderReviewFail(' db_query("INSERT INTO {foo} SET name=\'$name\'");');
$this->assertCoderReviewFail(' $sql = "INSERT INTO {foo} SET name=\'$name\'";');
$this->assertCoderReviewPass(' update_sql("INSERT INTO {foo} SET name=\'$name\'");');
$this->assertCoderReviewPass(' db_result(db_query("SELECT filename FROM {system} WHERE name = \'%s\'", "ad_$detail->adtype"));');
}
function testSecuritySQLUnquotedPlaceholders() {
$this->assertCoderReviewFail(' $sql = "SELECT * FROM {foo} WHERE name=%s";');
$this->assertCoderReviewFail(' $sql = "INSERT INTO {foo} (%s)";');
$this->assertCoderReviewFail(' $sql = "INSERT INTO {foo} (1,%s)";');
$this->assertCoderReviewFail(' $sql = "INSERT INTO {foo} (1, %s)";');
$this->assertCoderReviewPass(' $sql = "SELECT * FROM {foo} WHERE name=\'%s\'";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (\'%s\')";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (1,\'%s\')";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (1, \'%s\')";');
$this->assertCoderReviewPass(' $sql = "SELECT * FROM {foo} WHERE name=%d";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (%d)";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (1,%d)";');
$this->assertCoderReviewPass(' $sql = "INSERT INTO {foo} (1, %d)";');
}
function testSecurityDrupalSetMessage() {
$this->assertCoderReviewPass(' drupal_set_message(t("Here is some safe_data"));');
$this->assertCoderReviewPass(' drupal_set_message(t("Here is some @safe_data", array("@safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' drupal_set_message(t("Here is some %safe_data", array("%safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' drupal_set_message(t("Here is some @safe_data", $safe_data_array));');
$this->assertCoderReviewPass(' drupal_set_message(check_plain($tainted_data));');
$this->assertCoderReviewPass(' drupal_set_message(filter_xss_admin($tainted_data));');
$this->assertCoderReviewPass(' drupal_set_message(format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' drupal_set_message(check_markup($tainted_data));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_data = check_plain('mystring');\n drupal_set_message(\$tainted_data);\n}");
$this->assertCoderReviewFail(" function abc() {\n drupal_set_message(\$tainted_data);\n}");
$this->assertCoderReviewFail(' drupal_set_message(t($tainted_data));');
$this->assertCoderReviewFail(' drupal_set_message("Here is some ". $tainted_data);');
$this->assertCoderReviewFail(' drupal_set_message("Here is some $tainted_data");');
$this->assertCoderReviewFail(' drupal_set_message(t("Here is some ". $tainted_data));');
$this->assertCoderReviewFail(' drupal_set_message(t("Here is some !tainted_data", array("!tainted_data" => $tainted_data)));');
}
function testSecurityTriggerError() {
$this->assertCoderReviewPass(' trigger_error(t("Here is some safe_data"));');
$this->assertCoderReviewPass(' trigger_error(t("Here is some @safe_data", array("@safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' trigger_error(t("Here is some %safe_data", array("%safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' trigger_error(t("Here is some @safe_data", $safe_data_array));');
$this->assertCoderReviewPass(' trigger_error(check_plain($tainted_data));');
$this->assertCoderReviewPass(' trigger_error(filter_xss_admin($tainted_data));');
$this->assertCoderReviewPass(' trigger_error(format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' trigger_error(check_markup($tainted_data));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_data = check_plain('mystring');\n trigger_error(\$tainted_data);\n}");
$this->assertCoderReviewFail(" function abc() {\n trigger_error(\$tainted_data);\n}");
$this->assertCoderReviewFail(' trigger_error(t($tainted_data));');
$this->assertCoderReviewFail(' trigger_error("Here is some ". $tainted_data);');
$this->assertCoderReviewFail(' trigger_error("Here is some $tainted_data");');
$this->assertCoderReviewFail(' trigger_error(t("Here is some ". $tainted_data));');
$this->assertCoderReviewFail(' trigger_error(t("Here is some !tainted_data", array("!tainted_data" => $tainted_data));');
}
function testSecurityDrupalSetTitle() {
$this->assertCoderReviewPass(' drupal_set_title(t("Here is some safe_data"));');
$this->assertCoderReviewPass(' drupal_set_title(t("Here is some @safe_data", array("@safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' drupal_set_title(t("Here is some %safe_data", array("%safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' drupal_set_title(t("Here is some @safe_data", $safe_data_array));');
$this->assertCoderReviewPass(' drupal_set_title(check_plain($tainted_data));');
$this->assertCoderReviewPass(' drupal_set_title(filter_xss_admin($tainted_data));');
$this->assertCoderReviewPass(' drupal_set_title(format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' drupal_set_title(check_markup($tainted_data));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_data = check_plain('mystring');\n drupal_set_title(\$tainted_data);\n}");
$this->assertCoderReviewFail(" function abc() {\n drupal_set_title(\$tainted_data);\n}");
$this->assertCoderReviewFail(' drupal_set_title(t($tainted_data));');
$this->assertCoderReviewFail(' drupal_set_title("Here is some ". $tainted_data);');
$this->assertCoderReviewFail(' drupal_set_title("Here is some $tainted_data");');
$this->assertCoderReviewFail(' drupal_set_title(t("Here is some ". $tainted_data));');
$this->assertCoderReviewFail(' drupal_set_title(t("Here is some !tainted_data", array("!tainted_data" => $tainted_data));');
}
function testSecurityFormError() {
$this->assertCoderReviewPass(' form_error("name", t("Here is some safe_data"));');
$this->assertCoderReviewPass(' form_error($name, t("Here is some safe_data"));');
$this->assertCoderReviewPass(' form_error($name, t("Here is some @safe_data", array("@safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' form_error($name, t("Here is some %safe_data", array("%safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' form_error($name, t("Here is some @safe_data", $safe_data_array));');
$this->assertCoderReviewPass(' form_error($name, check_plain($tainted_data));');
$this->assertCoderReviewPass(' form_error($name, filter_xss_admin($tainted_data));');
$this->assertCoderReviewPass(' form_error($name, format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' form_error($name, check_markup($tainted_data));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_data = check_plain('mystring');\n form_error(\$name, \$tainted_data);\n}");
$this->assertCoderReviewFail(" function abc() {\n form_error(\$name, \$tainted_data);\n}");
$this->assertCoderReviewFail(' form_error($name, t($tainted_data));');
$this->assertCoderReviewFail(' form_error($name, "Here is some ". $tainted_data);');
$this->assertCoderReviewFail(' form_error($name, "Here is some $tainted_data");');
$this->assertCoderReviewFail(' form_error($name, t("Here is some ". $tainted_data));');
$this->assertCoderReviewFail(' form_error($name, t("Here is some !tainted_data", array("!tainted_data" => $tainted_data));');
}
function testSecurityFormSetError() {
$this->assertCoderReviewPass(' form_set_error("name", t("Here is some safe_data"));');
$this->assertCoderReviewPass(' form_set_error($name, t("Here is some safe_data"));');
$this->assertCoderReviewPass(' form_set_error($name, t("Here is some @safe_data", array("@safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' form_set_error($name, t("Here is some %safe_data", array("%safe_data" => $tainted_data));');
$this->assertCoderReviewPass(' form_set_error($name, t("Here is some @safe_data", $safe_data_array));');
$this->assertCoderReviewPass(' form_set_error($name, check_plain($tainted_data));');
$this->assertCoderReviewPass(' form_set_error($name, filter_xss_admin($tainted_data));');
$this->assertCoderReviewPass(' form_set_error($name, format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' form_set_error($name, check_markup($tainted_data));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_data = check_plain('mystring');\n form_set_error(\$name, \$tainted_data);\n}");
$this->assertCoderReviewFail(" function abc() {\n form_set_error(\$name, \$tainted_data);\n}");
$this->assertCoderReviewFail(' form_set_error($name, t($tainted_data));');
$this->assertCoderReviewFail(' form_set_error($name, "Here is some ". $tainted_data);');
$this->assertCoderReviewFail(' form_set_error($name, "Here is some $tainted_data");');
$this->assertCoderReviewFail(' form_set_error($name, t("Here is some ". $tainted_data));');
$this->assertCoderReviewFail(' form_set_error($name, t("Here is some !tainted_data", array("!tainted_data" => $tainted_data));');
}
function testSecurityConfirmForm() {
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path);');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some @safe_question", array("@safe_question" => $tainted_question), $path);');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some %safe_question", array("%safe_question" => $tainted_question), $path);');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some @safe_question", $safe_question_array), $path);');
$this->assertCoderReviewPass(' confirm_form($form, check_plain($tainted_question), $path);');
$this->assertCoderReviewPass(' confirm_form($form, filter_xss_admin($tainted_question), $path);');
$this->assertCoderReviewPass(' confirm_form($form, format_plural($tainted_count, "1 item", "@count items"), $path);');
$this->assertCoderReviewPass(' confirm_form($form, check_markup($tainted_question), $path);');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_question = check_plain('mystring');\n confirm_form(\$form, \$tainted_question, \$path);\n}");
$this->assertCoderReviewFail(" function abc() {\n confirm_form(\$form, \$tainted_question, \$path);\n}");
$this->assertCoderReviewFail(' confirm_form($form, t($tainted_question), $path);');
$this->assertCoderReviewFail(' confirm_form($form, "Here is some ". $tainted_question, $path);');
$this->assertCoderReviewFail(' confirm_form($form, "Here is some $tainted_question", $path);');
$this->assertCoderReviewFail(' confirm_form($form, t("Here is some ". $tainted_question), $path);');
$this->assertCoderReviewFail(' confirm_form($form, t("Here is some !tainted_question", array("!tainted_question" => $tainted_question), $path);');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("safe_description"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("some @safe_desc", array("@safe_desc" => $tainted_desc)));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("safe_description"), t("safe_yes"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("some @safe_desc", array("@safe_desc" => $tainted_desc)), t("safe_yes"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("safe_description"), t("safe_yes"), t("safe_no"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("some @safe_desc", array("@safe_desc" => $tainted_desc)), t("safe_yes"), t("safe_no"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, check_plain($tainted_desc"));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("safe_description"), check_plain($tainted_yes));');
$this->assertCoderReviewPass(' confirm_form($form, t("Here is some safe_question"), $path, t("safe_description"), t("safe_yes"), check_plain($tainted_no));');
$this->assertCoderReviewPass(' confirm_form($form, check_plain($tainted_question), $path, check_plain($tainted_desc), check_plain($tainted_yes), check_plain($tainted_no));');
$this->assertCoderReviewPass(' confirm_form($form, check_plain($tainted_question), $path, filter_xss_admin($tainted_desc));');
$this->assertCoderReviewPass(' confirm_form($form, check_plain($tainted_question), $path, check_markup($tainted_desc));');
$this->assertCoderReviewPass(' confirm_form($form, check_plain($tainted_question), $path, format_plural($tainted_count, "1 item", "@count items"));');
$this->assertCoderReviewPass(' confirm_form($form, format_plural($tainted_count, "1 item", "@count items"), $path, format_plural($tainted_desc, "1 item", "@count items"));');
$this->assertCoderReviewPass(" function abc() {\n \$tainted_q = check_plain('abc');\n \$tainted_desc = check_plain('string');\n confirm_form(\$form, \$tainted_q, \$path, \$tainted_desc);\n}");
$this->assertCoderReviewPass(" function abc() {\n \$tainted_desc = check_plain('mystring');\n confirm_form(\$form, check_plain(\$tainted_question), \$path, \$tainted_desc);\n}");
$this->assertCoderReviewFail(" function abc() {\n confirm_form(\$form, check_plain(\$tainted_question), \$path, \$tainted_desc);\n}");
$this->assertCoderReviewFail(" function abc() {\n confirm_form(\$form, check_plain(\$tainted_question), \$path, t(\$tainted_desc));\n}");
$this->assertCoderReviewFail(" function abc() {\n confirm_form(\$form, check_plain(\$tainted_question), \$path, check_plain(\$tainted_desc), t(\$yes));\n}");
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, check_plain($tainted_desc), $yes);');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, check_plain($tainted_desc), check_plain($yes), $no);');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, "Here is some ". $tainted_desc);');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, "Here is some $tainted_desc");');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, check_plain($tainted_desc), "Tainted " . $yes);');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, check_plain($tainted_desc), "Tainted $yes");');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, t("Here is some ". $tainted_desc));');
$this->assertCoderReviewFail(' confirm_form($form, check_plain($tainted_question), $path, t("Here is some !tainted_desc", array("!tainted_desc" => $tainted_desc)));');
}
function testSecurityPregReplaceEval() {
$this->assertCoderReviewPass(' $txt = preg_replace("@(]*>(.+?))@mi", "myfunction("\\2", "\\3")", $txt);');
$this->assertCoderReviewFail(' $txt = preg_replace("@(]*>(.+?))@emi", "myfunction("\\2", "\\3")", $txt);');
$this->assertCoderReviewPass(' $txt = preg_replace("/(]+href=?|