提问人:Andy Bbop 提问时间:1/7/2023 最后编辑:DharmanAndy Bbop 更新时间:1/8/2023 访问量:208
在 PHP 中,是否可以在不将变量传递到数据库查询的情况下进行 SQL 注入?[复制]
Is SQL injection possible without passing a variable into a database query in PHP? [duplicate]
问:
如果我有一个用户输入表单,但其中的数据纯粹用于在 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 从用户输入中获取数据并对其进行执行某种操作这一事实是否会使我面临风险?
答:
是的,这是 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
评论
这个答案是我同意的比尔·卡文(Bill Karwin)答案的补充。但是,您提出了一个有趣的观点,不,假设:
没有人可以弄乱会话变量,所以我很好
哦?怎么会这样?这在很大程度上取决于 PHP 代码的其余部分是否安全,您的生产环境是否得到适当的保护,避免了危险的脚本,并且系统编辑的本机 PHP 函数被锁定。
您的服务器系统/PHP系统/会话系统可能受到许多其他因素的威胁,例如cookie操纵,CSRF,XSS,甚至是您网站帐户上的文件系统破坏。
虽然这些问题本身就很严重,而且其中许多问题无论如何都可能导致MySQL妥协;不要仅仅因为一扇门看起来是锁着的,就认为所有的门都锁上了。
您的编辑 :
_SERVER美元[“PHP_SELF”] ...
服务器PHP_SELF可能会受到损害,不应使用。
您在上面做出这些假设的事实表明您的系统存在非零风险,因此您应该尽可能使用最安全的 SQL 交互方法。
评论
$_SERVER['PHP_SELF']
:-)
评论