本文概述
- 什么是SQL注入?
- 防止PHP中的SQL注入
- 防止使用WAF
- SQL注入和现代PHP框架
是的, 我们正在谈论的是立即销毁, 因为我不想以” 加强安全性” 和” 防止恶意访问” 这一la脚的常用术语来打开本文。 SQL注入是本书中的一个古老技巧, 每个人(每个开发人员)都非常了解它, 并且非常了解如何防止它。除了它们滑倒的那一个奇怪的时间, 结果可能是灾难性的。
【什么是SQL注入以及如何在PHP应用程序中进行预防()】如果你已经知道什么是SQL Injection, 请随时跳到本文的后半部分。但是对于那些刚进入Web开发领域并梦想担任更高级职位的人, 有必要进行一些介绍。
什么是SQL注入? 理解SQL注入的关键在于它的名称:SQL + Injection。这里的” 注射” 一词没有任何医学含义, 而是动词” 注射” 的用法。这两个词在一起传达了将SQL放入Web应用程序的想法。
将SQL放入Web应用程序中。 。 。嗯。 。 。那不是我们在做什么吗?是的, 但是我们不希望攻击者来驱动我们的数据库。让我们借助示例来了解这一点。
假设你要为本地电子商务商店构建一个典型的PHP网站, 因此你决定添加如下联系表格:
<
form action="record_message.php" method="POST">
<
label>
Your name<
/label>
<
input type="text" name="name">
<
label>
Your message<
/label>
<
textarea name="message" rows="5">
<
/textarea>
<
input type="submit" value="http://www.srcmini.com/Send">
<
/form>
并假设文件send_message.php将所有内容存储在数据库中, 以便商店所有者以后可以读取用户消息。它可能有一些这样的代码:
<
?php$name = $_POST['name'];
$message = $_POST['message'];
// check if this user already has a messagemysqli_query($conn, "SELECT * from messages where name = $name");
// Other code here
因此, 你首先尝试查看该用户是否已经有未读邮件。查询SELECT * from name = $ name的消息看起来很简单, 对吧?
错误!
我们天真地打开了立即销毁数据库的大门。为此, 攻击者必须满足以下条件:
- 该应用程序在SQL数据库上运行(今天, 几乎每个应用程序都在运行)
- 当前数据库连接对数据库具有” 编辑” 和” 删除” 权限
- 重要表的名称可以猜测
文章图片
乔截断订单;?是的先生!让我们看看由PHP脚本执行查询时查询将变成什么:
SELECT * FROM message where where name = Joe; 截断订单;
好的, 查询的第一部分有语法错误(” Joe” 周围没有引号), 但是分号强制MySQL引擎开始解释新的:截断订单。如此一来, 整个订单历史就消失了!
现在你已经了解了SQL Injection的工作原理, 现在该看看如何停止它。成功进行SQL注入需要满足的两个条件是:
- PHP脚本应具有对数据库的修改/删除特权。我认为这对所有应用程序都是如此, 并且你将无法将应用程序设置为只读。 ????猜猜是什么, 即使我们删除了所有修改权限, SQL注入仍然可以允许某人运行SELECT查询并查看所有数据库, 包括敏感数据。换句话说, 降低数据库访问级别不起作用, 并且你的应用程序仍然需要它。
- 用户输入正在处理中。 SQL注入可以起作用的唯一方法是当你接受用户的数据时。同样, 仅因为担心SQL注入而停止应用程序的所有输入是不切实际的。
清理用户输入
如果你使用的是较旧的PHP版本(5.5或更低版本, 并且在共享主机上经常发生这种情况), 明智的做法是通过mysql_real_escape_string()函数运行所有用户输入。基本上, 它会删除字符串中的所有特殊字符, 以使它们在被数据库使用时失去其含义。
例如, 如果你有一个像我一样的字符串, 则攻击者可以使用单引号(‘ )来操纵正在创建的数据库查询并导致SQL注入。通过mysql_real_escape_string()运行它会产生一个字符串, 在单引号中添加一个反斜杠, 以使其转义。结果, 整个字符串现在作为无害的字符串传递到数据库, 而不是能够参与查询操作。
这种方法有一个缺点:这是一种非常古老的技术, 与PHP中较旧的数据库访问形式一起出现。从PHP 7开始, 此功能甚至不再存在, 这使我们进入了下一个解决方案。
使用准备好的陈述
预备语句是一种使数据库查询更安全可靠的方法。我们的想法是, 我们首先将要发送的查询的结构告诉数据库, 而不是将原始查询发送到数据库。这就是我们” 准备” 声明的意思。准备好语句后, 我们会将信息作为参数化的输入传递, 以便数据库可以通过将输入插入我们之前发送的查询结构中来” 填补空白” 。这消除了输入可能具有的任何特殊功能, 从而在整个过程中将它们视为纯变量(或有效载荷, 如果需要)。准备好的语句如下所示:
<
?php$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection$conn = new mysqli($servername, $username, $password, $dbname);
// Check connectionif ($conn->
connect_error) {die("Connection failed: " . $conn->
connect_error);
}// prepare and bind$stmt = $conn->
prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->
bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute$firstname = "John";
$lastname = "Doe";
$email = "[email
protected]";
$stmt->
execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "[email
protected]";
$stmt->
execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email
protected]";
$stmt->
execute();
echo "New records created successfully";
$stmt->
close();
$conn->
close();
?>
我知道, 如果你不熟悉准备好的声明, 则过程听起来不必要地复杂, 但是这一概念值得你付出努力。这是一个很好的介绍。
对于那些已经熟悉PHP的PDO扩展并使用它来创建准备好的语句的人, 我有一点建议。
警告:设置PDO时要小心
使用PDO进行数据库访问时, 我们可能会陷入一种错误的安全感。 “ 嗯, 我正在使用PDO。现在, 我无需考虑其他任何事情” , 这就是我们通常的思维方式。的确, PDO(或MySQLi预准备的语句)足以阻止各种SQL注入攻击, 但是在设置它时必须小心。仅复制教程或先前项目中的代码并继续前进是很常见的, 但是此设置可以撤消所有操作:
$dbConnection->
setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
该设置的作用是告诉PDO模拟预备语句, 而不是实际使用数据库的预备语句功能。因此, PHP会将简单的查询字符串发送到数据库, 即使你的代码看起来像是在创建准备好的语句并设置参数。换句话说, 你像以前一样容易受到SQL注入的攻击。 ????
解决方案很简单:确保将此仿真设置为false。
$dbConnection->
setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
现在, PHP脚本被迫在数据库级别使用准备好的语句, 从而防止了各种SQL注入。
防止使用WAF 你是否知道还可以使用WAF(Web应用程序防火墙)保护Web应用程序免受SQL注入?
好吧, 不仅是SQL注入, 而且还有许多其他的第7层漏洞, 例如跨站点脚本, 破坏的身份验证, 跨站点伪造, 数据泄露等。你可以使用自托管(如Mod Security)或基于云的漏洞, 如下所述。
- JUICE
- 云耀斑
- Indusface
无论如何, 我的观点是, 现代的Web开发人员不必考虑SQL注入, 因此, 他们甚至不知道这种可能性。因此, 即使他们在应用程序中打开一个后门程序(可能是$ _GET查询参数, 也有旧习惯触发脏查询), 结果可能是灾难性的。因此, 最好花一些时间深入了解基础。
总结
SQL注入是对Web应用程序的非常讨厌的攻击, 但是很容易避免。正如我们在本文中看到的, 在处理用户输入时(请注意, SQL注入并不是处理用户输入带来的唯一威胁)并且查询数据库就足够了。就是说, 我们并非总是在Web框架的安全性下工作, 因此最好知道这种攻击而不是落伍。
推荐阅读
- 9个免费的有用在线SSL/TLS证书工具
- 通过API检测Web上的安全威胁
- 什么是社会工程(为什么要受到关注?)
- Admob横幅广告未在Android P中加载
- 在广告(Google Admob)Android之后运行一项功能
- Google InApp结算测试购买
- android in-app billing v3 api中的开发者有效负载应该是多少()
- App Rejected - Uploaded new binary - In App Purchase - 需要开发人员操作 - 等待审核
- 可以在Android中升级测试订阅吗()