在 PHP 中,是否可以在不将变量传递到数据库查询的情况下进行 SQL 注入?[复制]

Is SQL injection possible without passing a variable into a database query in PHP? [duplicate]

提问人:Andy Bbop 提问时间:1/7/2023 最后编辑:DharmanAndy Bbop 更新时间:1/8/2023 访问量:208

问:

如果我有一个用户输入表单,但其中的数据纯粹用于在 PHP 中进行比较,它是否会受到 SQL 注入风险的影响?我假设不是,只有我想通过 POST 或 GET 获取此类数据,然后将其放入数据库查询中,它才会成为一种风险。

例如。

假设我使用登录时创建的会话变量 user_id 返回一个数据集。

$sql="SELECT * FROM leads where user_id='".$_SESSION[user_id]."'"; 

没有人可以弄乱会话变量,所以我可以只使用它和一个沼泽标准mysqli_query来返回我的结果集,或者我收集。

我现在有一个小窗体,在选择框中包含一年中的月份,并使用 echo htmlspecialchars($_SERVER[“PHP_SELF”]);在提交表单时刷新页面,并筛选打印到 HTML 页面的报告结果。

if($results = mysqli_query($link, $sql)){
   while($row = mysqli_fetch_array($results )) {
        if($row["time_stamp"]>$POST["select_box") { Do some other stuff...} 

是否没有 SQL 注入的风险,因为我实际上没有将选择框值传递到数据库查询中?

或者,我通过 POST 从用户输入中获取数据并对其进行执行某种操作这一事实是否会使我面临风险?

php mysqli SQL注入

评论

6赞 Barmar 1/7/2023
为什么这很重要?SQL注入并不是使用预准备语句解决的唯一问题。不要浪费时间寻找不使用它们的借口。
2赞 Andy Bbop 1/7/2023
因为盲目地遵循范式而不正确理解它不是通往智慧的道路。
0赞 Sammitch 1/7/2023
当然,但 SQL 注入和预准备语句并不是晦涩难懂的东西。本网站上有大量相关问题和答案,互联网上其他地方的文章解释了各自的风险和收益。这个问题只是要求有人在你人为的例子案例的背景下向你重新解释所有这些。
0赞 Andy Bbop 1/7/2023
不,我想你会发现你们都想重新解释参数化查询,尽管它们实际上并不是问题的一部分。我只是想知道在不进入数据库查询的情况下使用一些帖子数据作为比较运算符是否存在风险,如果这么简单的问题有如此丰富的答案,为什么我找不到它们?

答:

3赞 Bill Karwin 1/7/2023 #1

是的,这是 SQL 注入风险。

您可以认为这是由您的登录系统设置的。你对此有多大信心?攻击者有没有办法污染您的会话数据?$_SESSION[user_id]

用户 ID 是否保证为整数?或者您的用户 ID 可以是字符串吗?如果是这样,它们是否具有会影响 SQL 查询语法的内容?比如它可以包含引号字符吗?

您的示例中还有一个隐藏的错误。 使用 PHP 常量作为键,它不一定与将常量定义为 以外的某个字符串相同。PHP 中未定义的常量默认为与该常量名称相同的字符串值,但如果该常量以某种方式被定义为其他字符串,它可能会引用不同的会话变量。$_SESSION[user_id]$_SESSION['user_id']'user_id'

诚然,这些都是晦涩难懂的案例。也许风险是最小的。但是,为什么要避开已知的SQL注入解决方案,即使用查询参数呢?

除此之外,使用查询参数而不是连接字符串和变量几乎总是更好。它使代码更易于阅读和调试,并且实际上对性能更好


回复您的评论:

您显示将查询结果与 POST 数据进行比较。那是在查询已经执行之后。

POST 数据不会影响 SQL 查询,因为您不会将 POST 数据插入到 SQL 查询中。

我专注于您的使用,因为这是您的示例中唯一可能涉及 SQL 注入的变量。$_SESSION

PS:与您的问题无关,但我认为如果您想引用 POST 输入的超全局变量,您应该在代码中使用 ,而不是$_POST$POST

评论

0赞 Andy Bbop 1/7/2023
您能详细说明一下如何吗?
0赞 Barmar 1/7/2023
我认为你需要解释风险,而不仅仅是一揽子的“是”。
0赞 Martin 1/7/2023
每个案件都是一个晦涩难懂的案件,直到它发生......那么无论它多么晦涩难懂,它都是鱼袋里的巨大痛苦!
0赞 Andy Bbop 1/7/2023
这些都是很好,也很有用,但问题不在于是否可以操纵会话变量,也不在于参数化查询是否可以防止其他类型的攻击。真正的问题是,仅仅通过与邮寄取货的价值进行比较,是否有可能处于危险之中。出于同样的原因,这也不是一个重复的问题。
0赞 Andy Bbop 1/7/2023
嗨,感谢您对此的额外回复,我最初的问题可能对太多其他切线开放,但这非常有用,谢谢。是的,只是对$POST马虎。
1赞 Martin 1/7/2023 #2

这个答案是我同意的比尔·卡文(Bill Karwin)答案的补充。但是,您提出了一个有趣的观点,不,假设:

没有人可以弄乱会话变量,所以我很好

哦?怎么会这样?这在很大程度上取决于 PHP 代码的其余部分是否安全,您的生产环境是否得到适当的保护,避免了危险的脚本,并且系统编辑的本机 PHP 函数被锁定。

您的服务器系统/PHP系统/会话系统可能受到许多其他因素的威胁,例如cookie操纵,CSRF,XSS,甚至是您网站帐户上的文件系统破坏。

虽然这些问题本身就很严重,而且其中许多问题无论如何都可能导致MySQL妥协;不要仅仅因为一扇门看起来是锁着的,就认为所有的门都锁上了。


您的编辑 :

_SERVER美元[“PHP_SELF”] ...

服务器PHP_SELF可能会受到损害,不应使用


您在上面做出这些假设的事实表明您的系统存在非零风险,因此您应该尽可能使用最安全的 SQL 交互方法。

评论

0赞 Andy Bbop 1/7/2023
“或者说,我聚集在一起。”我可能忘了提到会话变量是在参数化查询中生成的,因此只会在合法的登录尝试中生成,它是从该查询中绑定的数据创建的,并且基于数据库为该用户创建的唯一自动索引整数 ID 号,所以考虑到这些点,除非我已经打开了一个巨大的谷仓门, 会话变量应该非常安全,不会纵,不是这样吗?
0赞 Martin 1/7/2023
@AndyBbop变量的生成方式没什么大不了的,但它在系统上的存储和保护方式却是大问题。安全是洋葱圈,你说“相当安全”之类的话,它尖叫着它不是“完全安全的”,因为没有什么是完全安全的,因此你需要将变量的危险(无论多么小)考虑在你的SQL代码中,并使用参数化查询为你的帐户和系统添加一个额外的保护层。
0赞 Martin 1/7/2023
@AndyBbop从这个问答中得出的结论是:使用参数化查询。不要使用 .始终在安全洋葱中添加皮肤。探索 PHP 代码的最佳实践,并尽可能地保护自己。$_SERVER['PHP_SELF']:-)