这是我第一次创建一个PHP表单,它将使用INSERT INTO运行MySQL查询,以便在生产数据库中存储数据。这会通过“安全”还是过度杀人?
$orderText = $mysqli->real_escape_string(stripslashes(htmlentities((!isset($_POST["order_text"])?"undefined":$_POST["order_text"]))));
$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)");
$stmt->bind_param('s',$orderText);
$stmt->execute();
我不确定缺少SELECT *会如何影响我打开自己的风险,但似乎只使用INSERT的脚本更安全。真?
答案 0 :(得分:2)
您在第3行执行的变量绑定足以防止注入攻击。绑定是一个好主意,在我看来,总是完成。它不仅具有安全优势,而且还可以提高性能。
我认为在第1行执行额外的解析实际上是一个缺点: 它增加了复杂性,一些攻击利用了已知的数据转换,尽管使用绑定也可以减轻这些转换。
答案 1 :(得分:2)
你的问题中有很多错误的假设。
这当然是一种矫枉过正 让我们来看看非常难以阅读的zillion-nested-operator 语句:
你从错误的一端解决问题 您的主要目标是正确格式化查询。不要为想象中的“攻击者”辩护,而是用最诚实的数据来防止故障。虽然正确格式化的查询对于各种攻击都是无懈可击的,只是作为副作用 比方说,real_escape_string与安全性无关。它仅用于格式化字符串。查询中没有字符串(数据用引号括起来) - 因此这个函数完全没用(甚至有害)。
事实上,通过INSERT进行注入与通过SELECT进行注入同样具有灾难性。
最后,正确的代码是
$stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)");
$stmt->bind_param('s',$_POST["order_text"]);
$stmt->execute();
将订单文本打印回网站时,请使用htmlspecialchars()
就是这样。
答案 2 :(得分:1)
我会建议将来自客户,访客的所有内容视为威胁。不要放松,只关注一些SQL查询。实践好习惯没有限制。
答案 3 :(得分:1)
我同意Charles的看法,通过绑定param,你已经正确地逃避变量,消除了SQL注入攻击的可能性,而第1行的复杂性是过度的。当你跳转到PDO时会出现这种情况,因为没有特定的$ dbo-> escape()调用,因为使用prepare()/ bind()调用已经完成了转义工作。