我有一个来自,其中两个字段是以下
<select name="sortfield">
<option value="name" selected="selected">Name</option>
<option value="price">Price</option>
<option value="id">ID Code</option>
</select>
<select name="sortdir">
<option value="asc" selected="selected">Ascending</option>
<option value="desc">Descending</option>
</select>
这是通过下一页的$_REQUEST[]
获得的,然后将其添加到查询中以确定查询结果的排序方式,快速,脏,未经过消毒的方式是
$query .= "ORDER BY ".$_REQUEST['sortfield']." ".$_REQUEST['sortdir'];
显然这可能是sql注入的问题,我可以解决的一种方法是更改值并在进行查询交换值时有一个切换案例,类似这样
switch($_REQUEST['sortfield'])
{
case '5524879':
$query .= "ORDER BY name";
break;
case '4587532':
$query .= "ORDER BY price";
break;
default:
$query .= "ORDER BY id";
}
虽然这可以帮助防止sql注入它不是非常动态,因为如果查询/表结构发生变化,每次都必须更改页面,我想知道是否有更动态的方法来清理字符串而不是必须使用一个switch ... case
答案 0 :(得分:1)
更动态的方法是使用show fields创建一个表字段数组,并在检查sortfield
if ( !in_array( $_REQUEST['sortfield'], $table_fields ) ) {
// error
}
我还建议不要使用$ _REQUEST。你应该知道变量的来源。
$ _REQUEST中的变量通过GET提供给脚本, POST和COOKIE输入机制因此可以修改 远程用户,不可信任。的存在和秩序 此数组中列出的变量是根据PHP定义的 variables_order配置指令。
答案 1 :(得分:1)
是的,对于order by子句,您只能格式化动态标识符,而不是针对白名单进行检查。
if (!empty($_GET['sortfield']))
{
$query .= "ORDER BY `".str_replace("`","``",$_GET['sortfield'])."`";
} else {
$query .= "ORDER BY id";
}
请注意,它会保护您免受注入,但不会从SQL语法错误中保存 - 因此,最好还是验证字段名称。
此外,表中可能没有id
字段,因此此代码也不是非常动态。所以,最好还是坚持白名单。毕竟, 不是很难。有时手动修改比自动修改更好。