Php 防止仅插入查询上的SQL注入。这有什么大不了的吗?

Php 防止仅插入查询上的SQL注入。这有什么大不了的吗?,php,mysqli,sql-injection,prepared-statement,executequery,Php,Mysqli,Sql Injection,Prepared Statement,Executequery,这是我第一次创建一个PHP表单,该表单将使用INSERT INTO运行MySQL查询,以在生产数据库中存储数据。这会被认为是“安全的”还是“过度杀戮” $orderText = $mysqli->real_escape_string(stripslashes(htmlentities((!isset($_POST["order_text"])?"undefined":$_POST["order_text"])))); $stmt = $mysqli->prepare("INSERT

这是我第一次创建一个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的脚本更安全。是吗?

我建议将来自客户、您的访客的一切视为威胁。不要放松,只关注一些sql查询。养成一个好习惯是没有限制的

我建议将来自客户、访客的一切视为威胁。不要放松,只关注一些sql查询。养成一个好习惯是没有限制的

在第3行执行的变量绑定一般足以防止注入攻击。装订是一个好主意,在我看来,应该一直这样做。它不仅具有安全优势,还可以提高性能

我认为在第1行执行额外的解析实际上是一个缺点:
它增加了复杂性,有些攻击利用了已知的数据转换,不过使用绑定也可以缓解这些问题。

变量绑定(您在第3行中执行)一般足以防止注入攻击。装订是一个好主意,在我看来,应该一直这样做。它不仅具有安全优势,还可以提高性能

我认为在第1行执行额外的解析实际上是一个缺点:
它增加了复杂性,有些攻击利用了已知的数据转换,但使用绑定也可以减轻这些影响。

我同意Charles的观点,通过绑定参数,您已经正确地逃逸了变量,从而消除了SQL注入攻击的机会,而第1行的复杂性也太高了。当您跳转到时,这一点很明显,因为没有特定的$dbo->escape()调用,因为prepare()/bind()调用已经完成了转义工作。

我同意Charles的观点,通过绑定参数,您已经正确地转义了变量,消除了SQL注入攻击的机会,而1号线的复杂性是过分的。当您跳转到时,这一点很明显,因为没有特定的$dbo->escape()调用,因为prepare()/bind()调用已经完成了转义工作。

在您的问题中有大量错误的假设

  • 这当然是一种过度的杀伤力。
    让我们检查一下您极难阅读的zillion嵌套运算符语句:

    • 存储“未定义”一词毫无意义。数据库对未定义的字段有一个特殊标记—空值。或者仅仅是一个空字符串就足够了
    • 无条件的条带斜杠不会增加安全性,但可能会破坏数据
    • htmlentities与SQL安全性无关,可能在其他方面有助于站点安全,也可能破坏数据
    • 转义不会增加安全性,并且会破坏数据
  • 你把问题从错误的方向解决了。
    您的主要目标是正确设置查询的格式。不是为了防御假想的“攻击者”,而是为了用最诚实的数据隐藏故障。虽然格式正确,但作为一种副作用,查询不会受到各种攻击。
    比如说,真正的逃逸字符串与安全无关。它仅用于格式化字符串。查询中没有字符串(数据用引号括起来),因此此函数完全没有用处(甚至有害)

  • 事实上,通过INSERT注入的灾难性不亚于通过SELECT注入

  • 最后,正确的代码应该是

    $stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)"); 
    $stmt->bind_param('s',$_POST["order_text"]); 
    $stmt->execute(); 
    
    将订单文本打印回站点时,请使用
    htmlspecialchars()


    就这些。

    你的问题中有大量错误的假设

  • 这当然是一种过度的杀伤力。
    让我们检查一下您极难阅读的zillion嵌套运算符语句:

    • 存储“未定义”一词毫无意义。数据库对未定义的字段有一个特殊标记—空值。或者仅仅是一个空字符串就足够了
    • 无条件的条带斜杠不会增加安全性,但可能会破坏数据
    • htmlentities与SQL安全性无关,可能在其他方面有助于站点安全,也可能破坏数据
    • 转义不会增加安全性,并且会破坏数据
  • 你把问题从错误的方向解决了。
    您的主要目标是正确设置查询的格式。不是为了防御假想的“攻击者”,而是为了用最诚实的数据隐藏故障。虽然格式正确,但作为一种副作用,查询不会受到各种攻击。
    比如说,真正的逃逸字符串与安全无关。它仅用于格式化字符串。查询中没有字符串(数据用引号括起来),因此此函数完全没有用处(甚至有害)

  • 事实上,通过INSERT注入的灾难性不亚于通过SELECT注入

  • 最后,正确的代码应该是

    $stmt = $mysqli->prepare("INSERT INTO testtable (order_text) VALUES (?)"); 
    $stmt->bind_param('s',$_POST["order_text"]); 
    $stmt->execute(); 
    
    将订单文本打印回站点时,请使用
    htmlspecialchars()


    仅此而已。

    我提到的一个简单的攻击示例,尽管这个特定的示例不适用于本例:黑客通过实验了解到网站首先从“名称”字段中删除SQL关键字(插入等),然后删除引号。SQL注入可能包括一个“名称”,由类似“插入…”的内容组成。如果按照上述顺序进行解析,删除勾号会将“in'SERT”变为“INSERT”,这可能是一种有效的SQL注入攻击。@Col.Shrapnel:这不是迷信;这是一种被称为“二阶SQL注入”的有良好记录的黑客技术。你可以在很多书中读到它。例如,看看“Byp”