安全转义表名/列名

qwe*_*ymk 5 php mysql sql security pdo

我在 php 中使用 PDO,因此无法使用准备好的语句转义表名或列名。以下是我自己实现它的万无一失的方法:

$tn = str_replace('`', '', $_REQUEST['tn']);
$column = str_replace('`', '', $_REQUEST['column']);
$sql = "SELECT * FROM `tn ` WHERE `column` = 23";
print_r(
    $pdo->query($sql)->fetchAll()
);
Run Code Online (Sandbox Code Playgroud)

或者还有什么可以攻击的途径吗?

goa*_*oat 4

您可以通过询问数据库哪些列对于给定数据库表有效来使用动态白名单。虽然是多了一个sql查询,但是安全性还是不错的。

select COLUMN_NAME 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA = :databaseName
  and TABLE_NAME = :tableName
Run Code Online (Sandbox Code Playgroud)

获取结果,然后确保所有动态列名称都在结果集中。

我相信意见已包含在INFORMATION_SCHEMA.COLUMNS,所以它应该只是简单的工作。

然后,在组装动态 sql 时,只需在经过验证的列名称周围使用反引号即可(我假设您使用纯 ascii 列名称,否则您可能需要额外考虑)。

  • 你已经犯了错误(不允许使用句点,请参阅http://dev.mysql.com/doc/refman/5.0/en/identifiers.html),除非你真正理解你在做什么,包括很好地理解字符集和 unicode,只需使用白名单,而无需担心您没有的性能问题。或者,将表和列名称限制为长度有限的 a-zA-Z0-9_ 以方便验证。避免使用 unicode 和非 ASCII 字符。 (3认同)