- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
NOTE: This is not a question about what is SQL Injection, but rather a question to clear up what the actual vulnerability, particularly given some specific test cases.
Background: Please see this video by a group called Modern Rouge. Or, you can ignore it, as it's kind of oversimplified for people who don't have technical skills and aren't already familiar with SQL Injection. I will point our the important part when it's needed.
所以,对于那些不知道什么是 SQL 注入(inject)的人(我只是为了完整性而添加这个,并为我的特定问题提供背景),假设我有这样的 PHP 代码:
$query = "SELECT * FROM users WHERE username='$username'";
这段代码很容易受到攻击,因为假设恶意最终用户将他们的用户名输入为 ' 或 1=1;--
,这可能会导致最终查询
SELECT * FROM users WHERE username='' or 1=1;--'
这没有达到预期的效果。
那么,现在观看有关 the 4:00 mark 的视频.
他们在测试网站上给出的 SQL 注入(inject)示例,他们使用 SQL 注入(inject)来绕过密码检查。
这是我不明白的,在现实生活中,我不会改为在 PHP 中检查密码,从而使这个特定示例变得毫无用处吗?例如:
if($userRecordFromDB["pwd"] == $pwd) { // User authenticated.
SQL 注入(inject)无法绕过我的 PHP 身份验证,我说得对吗?这里的漏洞是什么?除非我将密码检查与我的查询相关联(我承认本示例可以这样做),否则即使我有易受攻击的查询,我的网站也不应该易受攻击。
第二个相关问题:视频继续暗示单个漏洞可能允许攻击者访问我的整个数据库!我假设他们的意思是攻击者可以做这样的事情:
SELECT * FROM users WHERE username='' or 1=1; SELECT * FROM creditInformationTable where 1=1--'
$username
当然是 ' 或 1=1; SELECT * FROM creditInformationTable where 1=1--
然而,这也让我感到困惑。除非我将这些数据放入一个漂亮的表或其他东西中,否则数据不会永远不会离开后端,即使查询是易受攻击的吗?除非我不小心给了他们这些信息,否则他们怎么可能得到这些信息?
这让我想到了一个更大的问题:SQL 注入(inject)的危险是什么?这纯粹是理论上的,还是存在攻击者可以通过纯 SQL 注入(inject)执行登录或访问数据库中的所有表等操作的真实案例?
编辑:从头开始。让我缩小一点。
它如何离开后端?即使某些东西查询了错误的东西,我的攻击者怎么会得到它? PDO 和 SQLI 等数据库 API 将信息返回给 PHP,不是结果页面。一个编写良好的 PHP 脚本难道不应该捕捉到错误的数据,或者至少不应该将其全部回显给用户吗?
最佳答案
SQL 注入(inject)不是理论上的。几乎每个月都有关于使用 SQL 注入(inject)实现的真实数据泄露的新闻报道。有一个收集它们的好网站:https://codecurmudgeon.com/wp/sql-injection-hall-of-shame/
这是上个月的一个不错的:
https://motherboard.vice.com/en_us/article/vba5nb/fornite-login-hack-epic-games-website
Bugs on Epic Games Site Allowed Hackers to Login to Any ‘Fortnite’ Player’s Account
...
That page, which is now offline, contained two vulnerabilities that are often found in websites: an SQL Injection (or SQLi), and a Cross-Site Scripting (or XSS), according to Check Point researchers.
关于您提供的示例,我确实建议在应用程序代码中验证密码。然后你可以区分“找不到帐户”和“找到帐户,但密码错误”(你不想向用户透露这个,但你可能想记录错误,如果他们可能会锁定帐户密码尝试失败次数太多)。
但无论如何,SQL 语句容易受到 SQL 注入(inject)攻击。不仅使用您展示的“OR 1=1”技巧,而且如果您可以欺骗查询运行基于 UNION 的 SQL 查询:
$query = "SELECT * FROM users WHERE username='' UNION ALL SELECT * FROM INFORMATION_SCHEMA.TABLES -- '";
^^ $username ...
如果攻击者可以在您的应用程序中找到 SQL 查询(不一定是按帐户名搜索),他们就可以使用此技术来查询您的所有表。然后他们可以进一步使用 UNION 技术来查询所有表中的数据,一旦他们知道他们的名字。
关于您的后续问题:
“数据如何离开后端?”
考虑一下您的密码检查代码(针对上述查询)是否如下所示:
$query = "SELECT id, username, password_hashed FROM users WHERE username='$username'";
$stmt = $pdo->query($query);
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
if (!password_verify($password, $row['password_hashed'])) {
die("Invalid login for user {$row['username']}");
}
}
看到了吗? SQL 查询的结果输出给用户。对于此代码的开发人员来说,很明显,因为他们只是查询了 $username
,所以这就是查询将返回的值。他们认为 $row['username']
可以安全使用。
但它不是——它是来自 UNION 另一部分的一些数据。通过使用 CONCAT() 和 GROUP_CONCAT(),攻击者甚至可以将多行的多列放在一起。 他们确实这样做了。他们可能需要多次尝试才能让他们的攻击查询在正确的位置有正确数量的列,但他们显然没有更好的事情可做。
关于php - SQL - SQL 注入(inject)的真正危险是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54917328/
编辑:澄清一下,我明白为什么这段代码不起作用,我并不是要修复它,而是想了解如果这段代码可以在没有语义错误的情况下编译会有什么危险。 我发现下面的代码会导致静态语义错误。我知道这是因为 std::lis
我想知道 C# 枚举以及重复值会发生什么。我创建了以下小程序来测试: namespace ConsoleTest { enum TestEnum { FirstElem
正如我在另一个 SO 问题中指出的那样,我遇到了 this article .当我通过 MSVC7.1 编译 boost 1.40 时出现了这个问题,并且弹出了几个 C4251 警告。 现在,在阅读上
我有以下弹出窗口代码(客户端请求)。它使用 eval ,我知道这是危险的。有没有办法重写下面的脚本,使其不使用 (eval)? /* exported popup_default , popup_he
NTFS 文件可以有对象 ID。可以使用 FSCTL_SET_OBJECT_ID 设置这些 ID .然而,msdn article说: Modifying an object identifier c
我一直在学习命令行参数解析。关于这个已经有很长的线索了,我不想在这里挑起一个: Using getopts in bash shell script to get long and short com
这个问题在这里已经有了答案: How to configure ContextMenu buttons for delete and disabled in SwiftUI? (4 个回答) 4 个月
为什么在 linux 的中断处理程序中禁止 printk 或 (I/O)。?在什么情况下中断处理程序中的 I/O 会导致 linux 系统中的死锁? 最佳答案 关于 printk(),它是侵入性的。例
不是 Invoking virtual function and pure-virtual function from a constructor 的重复项: 以前的问题与 C++ 03 相关,而不是
我正在使用 lateinit 属性以避免使用 ?运算符(operator)。我有很多 View 属性是第一次在 getViews() 函数中分配的。如果该功能不存在,我的应用程序将与来自 Kotlin
我最近在使用 fputs 时遇到了问题:当使用 fputs 在文本文件中打印一些字符串时,我碰巧得到了除 A-Z、a-z、0-9 之外的其他字符(不属于字符串的字符) .我绝对确保所有字符串都以空字符
在仅包含字节数组的结构上使用 #pragma pack(1) 是否危险/有风险?例如。这个: #pragma pack(1) struct RpcMessage { uint8_t proto
我是一名优秀的程序员,十分优秀!