我有一个使用 php 生成的 sql 查询。它返回具有与搜索词匹配的字段的任何记录的代理键,以及在其他表中具有与搜索词匹配的相关记录的任何记录的代理键。
我将这些表合并为一个,然后使用一个单独的函数来检索表中包含的列的列表(我想允许添加到表中而无需重新编写 php 代码以减少持续维护)。
然后使用这段代码
foreach ($col_array as $cur_col) {
foreach ($search_terms_array as $term_searching) {
$qry_string.="UPPER(";
$qry_string.=$cur_col;
$qry_string.=") like '%";
$qry_string.=strtoupper($term_searching);
$qry_string.="%' or ";
}
}
生成查询字符串的其余部分
select tbl_sub_model.sub_model_sk from tbl_sub_model inner join [about 10 other tables]
where [much code removed] or UPPER(tbl_model.image_id) like '%HONDA%' or
UPPER(tbl_model.image_id) like '%ACCORD%' or UPPER(tbl_badge.sub_model_sk) like '%HONDA%'
or UPPER(tbl_badge.sub_model_sk) like '%ACCORD%' or UPPER(tbl_badge.badge) like '%HONDA%'
or UPPER(tbl_badge.badge) like '%ACCORD%' group by tbl_sub_model.sub_model_sk
它做我想做的事,但它容易受到 sql 注入(inject)的攻击。我一直在用 pdo 替换我的 mysql_* 代码以防止这种情况发生,但是我将如何保护这个代码超出了我的范围。
所以我的问题是,如何以安全的方式搜索所有这些表?
最佳答案
这是一个解决方案,要求数据库将搜索词大写,并用 '%'
通配符修饰它们:
$parameters = array();
$conditions = array();
foreach ($col_array as $cur_col) {
foreach ($search_terms_array as $term_searching) {
$conditions[] = "UPPER( $cur_col ) LIKE CONCAT('%', UPPER(?), '%')";
$parameters[] = $term_searching;
}
}
$STH = $DBH->prepare('SELECT fields FROM tbl WHERE ' . implode(' OR ', $conditions));
$STH->execute($parameters);
注意事项:
- 我们让 MySQL 对用户的搜索词调用 UPPER(),而不是让 PHP 调用 strtoupper()
这应该限制可能的搞笑/混淆的不匹配字符集问题。所有规范化都在一个地方进行,并且尽可能接近使用时刻。 - CONCAT() 是 MySQL 特有的
但是,当您标记问题[mysql]
时,这可能不是问题。 - 此查询与您的原始查询一样,将无法建立索引。
关于php - 防止对具有可变(和大)列数的查询进行 sql 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13409929/