预准备语句不允许参数化表名。为了确保不能插入任何代码,我想使用ctype_alnum来验证进入数据库模块的所有表名(删除下划线后)以保护应用程序免受其他部分的错误。
function insert($table) {
if(!ctype_alnum(str_replace("_", "", $table)))
throw new Exception("Invalid table name");
$sql = "INSERT INTO $table VALUES value=:value";
#... prepare and execute
}
这些攻击是否足够?我正在考虑例如multibyte character exploits
答案 0 :(得分:8)
我不知道在这种情况下会起作用的任何攻击但我不会按照您的方式执行此操作,因为$table
也可以包含可能不存在的表。
你应该接受$tables
的白名单,所以我会这样做:
function insert($table)
{
$table = trim($table);
if (!ctype_alnum(str_replace("_", "", $table))
|| !in_array($table, $this->tables)
) {
throw new Exception("Invalid table name");
}
$sql = "INSERT INTO $table VALUES value=:value";
echo $sql;
#... prepare and execute
}
它将确保您的代码安全,如果有人拼错了表名,您甚至不会尝试执行代码。实际上,在这种情况下,您可以在检查白名单数组中是否存在值时从条件中删除ctype_alnum
。