我可以将参数作为比较运算符绑定到 PDO 语句吗?
这种代码
class opinion
{
private $dbh;
var $opinionid,$opinion,$note,$actorid,$dateposted;
var $isnew=FALSE;
function loadby($column,$value,$operator="="){
$dbh = new PDO(I deleted parameters here);
$statement=$dbh->prepare("select * from fe_opinion where :column :operator :value");
$statement->bindParam(":column", $column);
$statement->bindParam(":value", $value);
$statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL
$statement->bindColumn("opinionid", $this->opinionid);
$statement->bindColumn("opinion", $this->opinion);
$statement->bindColumn("note", $this->note);
$statement->bindColumn("actorid", $this->actorid);
$statement->bindColumn("dateposted", $this->dateposted);
$statement->fetch();
return $statement->rowCount(); //please be 1
}
}
注入安全吗?
$statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL
我可以将参数作为比较运算符绑定到 PDO 语句吗?
Is this code
class opinion
{
private $dbh;
var $opinionid,$opinion,$note,$actorid,$dateposted;
var $isnew=FALSE;
function loadby($column,$value,$operator="="){
$dbh = new PDO(I deleted parameters here);
$statement=$dbh->prepare("select * from fe_opinion where :column :operator :value");
$statement->bindParam(":column", $column);
$statement->bindParam(":value", $value);
$statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL
$statement->bindColumn("opinionid", $this->opinionid);
$statement->bindColumn("opinion", $this->opinion);
$statement->bindColumn("note", $this->note);
$statement->bindColumn("actorid", $this->actorid);
$statement->bindColumn("dateposted", $this->dateposted);
$statement->fetch();
return $statement->rowCount(); //please be 1
}
}
injection safe?
$statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL
Can I bind a parameter to a PDO statement as a comparison operator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,你不能像那样绑定运算符。作为一种解决方法,您可以动态创建“基本”SQL 查询并使用运算符白名单(这是非常合适的)来保持注入安全:
除此之外,其余的都很好,并且“根据定义”是防注入的。
No, you cannot bind operators like that. As a workaround, you can dynamically create the "base" SQL query and use an operator whitelist (which is quite appropriate) to remain safe from injection:
Apart from this, the rest is fine and injection-proof "by definition".
根据 DBMS 和 PHP 驱动程序,准备好的语句可以是“真实的”或模拟的。
在第一种情况下,绑定参数由 DBMS 直接处理。在这种情况下,将运算符作为参数处理可能会触发语法错误。 SQL 解析器将分析查询,甚至不查看参数,也不会找到有效的 SQL 代码来处理。
在第二种情况下,绑定参数由驱动程序模拟:输入值被插入到 SQL 代码中(具有足够的转义),并且 DBMS 接收完整的常规查询。我不太确定当前的驱动程序将如何表现(我需要测试它),但即使他们不抱怨无效的 SQL,他们迟早会碰壁:SQL 运算符不是字符串。
现在,有一天实现这个功能会是一个很好的功能吗?我怀疑这一点:
Depending on the DBMS and PHP driver, prepared statements can be "real" or emulated.
In the first case, bind parameters are handled directly by the DBMS. In such case, handling an operator as parameter will probably trigger a syntax error. The SQL parser will analyse the query without even looking at parameters and will not find valid SQL code to work on.
In the second case, bind parameters are emulated by the driver: input values get inserted into SQL code (with adequate escaping) and the DBMS receives a complete regular query. I'm not really sure about how current drivers will behave (I'd need to test it) but even if they don't complain about invalid SQL, they'll hit a wall sooner or later: SQL operators are not strings.
Now, would it be a nice feature to get implemented some day? I doubt it is:
正如评论中提到的,我认为不可能逃脱操作员并让它按您的预期工作。生成的查询可能类似于:
您不需要转义运算符来避免注入攻击,您可以在将运算符附加到字符串之前验证运算符,请考虑:
As mentioned in comment I don't think it's possible to escape the operator and have it work as you expect. The resulting query would probably look something like:
You don't need to escape the operator to avoid injection attacks, you can validate your operator before appending it to the string, consider:
你实际上可以做到。 sql 变得更加复杂。根据组合的数量,SQL 可能会变得非常庞大。但是,有时当只有几个选择时,这很好。
:value 也可以是另一列,但是您需要再次嵌套另一个 case 构造,就像第一列一样,并且组合现在确实在飙升。
不管怎样...只是想证明这是可以做到的。
You can actually do it. The sql just gets more complicated. Depending on the number of combinations, the sql can get really huge. But, sometimes when there's only a few choices, its nice.
The :value could be another column too, but you'll need to nest yet again another case construct like for the first column, and the combinations are really soaring now.
Anyway... just wanted to show it can be done.