Joe*_*ssi 5 php mysql pdo sql-injection prepared-statement
我正在尝试编写一个函数,该函数在允许进行的查询中具有多种功能,但也可以防止注入。下面的代码按原样抛出错误,但是如果我使用“名称”而不是“:field”运行它,则可以正常工作。
$field = "name";
$value = "joe";
function selectquery($field, $value)
{
global $dbcon;
$select = $dbcon->prepare('SELECT * FROM tester1 WHERE :field = :value');
if($select->execute(array(':field' => $field, ':value' => $value)));
{
$row = $select->fetch();
for ($i=0; $i<3; $i++)
{
echo $row[$i]."\n";
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何允许在不允许注入攻击的情况下更改表/字段/值?mysql_real_escape_string()似乎有点倒退。有任何想法吗?
我可能是错的,但我不相信您可以在 PDO 中提供字段作为参数。
为什么不直接将其指定为函数的参数呢?与用户提供的数据不同,这些字段是有限的、定义明确的并且不会经常更改。如在
selectquery('name',$value);
Run Code Online (Sandbox Code Playgroud)
并让您的查询成为
$field = "name";
$value = "joe";
function selectquery($field, $value)
{
global $dbcon;
$select=$dbcon->prepare("SELECT * FROM tester1 WHERE $field = :value");
if($select->execute(array(':value' => $value)));
//etcetera
Run Code Online (Sandbox Code Playgroud)
由于您自己提供函数调用的字段名称,因此这是安全的,除非您担心会通过 SQL 注入攻击自己。
如果由于某种奇怪的原因,字段的名称来自用户输入,您可以创建一个允许字段的数组。这样,您就可以安全地避免注入,因为这些值只能来自您的数组。我不知道为什么字段名称会来自用户输入,因此不受信任,除非您正在制作 API?否则可能有更好的方法来实现目标。
无论如何,这将是一个潜在的解决方案,对表名使用白名单:
$field = "name";
$value = "joe";
$allowed_fields=array('name','other_name','sandwich');
function selectquery($field_name, $value)
{
global $dbcon,$allowed_fields;
if(!in_array($field_name,$allowed_fields)){ return false; }
else{ $field=$field_name; }
$select=$dbcon->prepare("SELECT * FROM tester1 WHERE $field = :value");
if($select->execute(array(':value' => $value)));
//etcetera
Run Code Online (Sandbox Code Playgroud)