【问题标题】:filter_input and mysqli_real_escape_string for integers整数的 filter_input 和 mysqli_real_escape_string
【发布时间】:2012-03-11 07:04:24
【问题描述】:

我正在开发一个供内部使用的简单 PHP 数据库应用程序,但希望将其编码为最佳实践。我的一些页面正在接收来自 GET 请求的整数值,我只是想知道真正需要多少验证和清理。

目前我正在使用具有指定最小值和最大值的$num = filter_input(INPUT_GET, 'num', FILTER_VALIDATE_INT, $num_options);。如果$num == false

,从这里我将退出并显示错误消息

是不是还要用$mysqli->real_escape_string($num);

目前我不打扰,因为我认为使用整数进行 SQL 注入非常困难......

谢谢,

凯文

更新:为了澄清我正在做的查询看起来像这样

$sql = "SELECT employeeID, concat(FirstName, ' ', LastName) as Name FROM employee WHERE employeeID='$num'";

【问题讨论】:

    标签: php mysqli mysql-real-escape-string filter-input


    【解决方案1】:

    我看到您使用 mysqli,您最好的安全选择是查看 Prepared Statements。

    PHP mysqli Prepared Statements

    举个例子有点牵强,但上面的链接有深入的例子。
    一旦你掌握了它,并建立你的班级。这实际上只是一个普通的 sql 查询,而不是包含您使用的值?

    "SELECT * FROM account WHERE username = ? AND password = ?"
    

    然后你将你的值绑定到语句:

    array("bradley", "Passw0rd");
    

    简而言之,安全性来自您自己没有将值连接到查询字符串中的事实。使其不易发生 sql 注入。

    【讨论】:

    • 哦,哎呀,我想我跑题了,抱歉。你主要关心整数。但我想用准备好的语句你必须指定字符串/整数,这样我相信这可以解决你的整数注入问题。
    • 我刚刚发布了我正在使用的确切查询。我对准备好的陈述很熟悉,我只是认为它们在这种情况下有点矫枉过正。
    • @KevinMorse 准备好的语句不能是矫枉过正
    • 我同意,我已经把我所有的数据库代码都锁在了它的班级里,我经常去调整它。但我基本上将它用于所有事情,除非它是一个快速调试语句,我只是插入一个快速的原始 $db->query("") :D
    • @KevinMorse 让您知道,准备好的语句只有在整个站点 SQL 操作中毫无例外地使用时才能可靠。否则就不行了。
    【解决方案2】:

    像许多其他 PHP 用户一样,您正在错误地转义。你把它当作某种魔杖,它可以让一些“邪恶的角色”“安全”。
    这是错误的想法。
    尽管prepared statements可以被视为一种魔杖,但转义并不是“SQL注入保护”的同义词。它只是一个字符串语法规则——不多也不少。

    是否也需要使用$mysqli->real_escape_string($num);

    这是无关紧要的问题。
    逃避或不逃避决定必须绑定到 SQL,而不是数据源或任何验证:

    • real_escape_string() 必须用于 sql 字符串,即用引号括起来的查询部分。必须无条件使用,尽管之前有任何操作。
    • 对于查询的任何其他部分 real_escape_string() 完全没用。

    说明:
    可以更改数据验证规则。
    而 SQL 构建规则必须是明确的和无条件的。 为了让开发者永远不会问自己这样的问题
    事实上,这是完全不同的事情:数据验证和查询构建。为什么要记住这些细节并相应地构建查询?为什么不基于一些通用规则构建查询,完全与数据性质无关?

    所以,再次回答你的问题:

    • 如果您按原样将数据添加到查询中,不带引号,那么 real_escape_string() 在这种情况下将完全没有用,但强制转换/验证变得必不可少。
    • 如果您使用准备好的语句将数据添加到查询中,real_escape_string() 将完全无用甚至有害。
    • 如果您将数据添加到引号中的查询中 - 在这种情况下,您应该执行 real_escape_string()。
    • 还值得一提的是,如果您将数据作为 SQL 语言的一部分(作为标识符或 SQL 关键字)添加到查询中,那么 real_escape_string() 以及准备好的语句也是完全没用的。白名单是您唯一的朋友

    【讨论】:

    • 如果我理解正确,您是说如果我没有将其插入到 SQL 查询的引用部分中,它就不需要转义?
    • 如果您不将其插入到 SQL 的引用部分中,转义将变得完全、绝对和完全无用。
    • SQL 中引用的部分是什么意思?请查看我现在在原始帖子中发布的确切查询。
    • 您的 $num 用撇号引用。因此,您将其视为字符串。 SQL 中的字符串需要转义。
    • 是的,在某种程度上。至少当您的标识符将更改为字符串时,您会收到 SQL 错误通知。但是 PHP 用户编写代码的方式让我感到恶心。
    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2017-09-14
    相关资源
    最近更新 更多