什么是SQL注入(SQLi)以及如何防止它
SQL注入(SQLi)是一种注入攻击,它使执行恶意SQL语句成为可能。这些语句控制Web应用程序后面的数据库服务器。攻击者可以使用SQL Injection漏洞绕过应用程序安全措施。他们可以遍历网页或Web应用程序的身份验证和授权,并检索整个SQL数据库的内容。他们还可以使用SQL Injection添加,修改和删除数据库中的记录。
SQL注入漏洞可能会影响使用SQL数据库(例如MySQL,Oracle,SQL Server或其他)的任何网站或Web应用程序。犯罪分子可能会使用它来未经授权地访问您的敏感数据:客户信息,个人数据,商业秘密,知识产权等。SQL注入攻击是最古老,最普遍和最危险的Web应用程序漏洞之一。OWASP组织(开放式Web应用程序安全性项目)在其OWASP Top 10 2017文档中列出了注入,这是对Web应用程序安全性的头号威胁。
如何以及为什么执行SQL注入攻击
要进行SQL注入攻击,攻击者必须首先在网页或Web应用程序中找到易受攻击的用户输入。具有SQL注入漏洞的网页或Web应用程序直接在SQL查询中使用此类用户输入。攻击者可以创建输入内容。此类内容通常称为恶意有效payload,是攻击的关键部分。攻击者发送此内容后,将在数据库中执行恶意SQL命令。
SQL是一种查询语言,旨在管理关系数据库中存储的数据。您可以使用它来访问,修改和删除数据。许多Web应用程序和网站都将所有数据存储在SQL数据库中。在某些情况下,您还可以使用SQL命令来运行操作系统命令。因此,成功的SQL Injection攻击可能会带来非常严重的后果。
-
攻击者可以使用SQL注入在数据库中查找其他用户的凭据。然后,他们可以模拟这些用户。模拟用户可以是具有所有数据库特权的数据库管理员。
-
SQL使您可以从数据库中选择和输出数据。SQL注入漏洞可能使攻击者获得对数据库服务器中所有数据的完全访问权限。
-
SQL还允许您更改数据库中的数据并添加新数据。例如,在金融应用程序中,攻击者可以使用SQL注入来更改余额,使交易无效或将资金转入其帐户。
-
您可以使用SQL从数据库中删除记录,甚至删除表。即使管理员进行数据库备份,删除数据也可能会影响应用程序的可用性,直到还原数据库为止。另外,备份可能不会覆盖最新数据。
-
在某些数据库服务器中,您可以使用数据库服务器访问操作系统。这可能是有意或无意的。在这种情况下,攻击者可以使用SQL注入作为初始媒介,然后攻击防火墙后面的内部网络。
SQL注入攻击有几种类型:带内SQLi(使用数据库错误或UNION命令),盲SQLi和带外SQLi。
简单的SQL注入示例
第一个例子很简单。它显示了攻击者如何利用SQL Injection漏洞来绕过应用程序安全性并以管理员身份进行身份验证。
以下脚本是在Web服务器上执行的伪代码。这是使用用户名和密码进行身份验证的简单示例。示例数据库有一个表users
,该表包含以下列:username
和password
。
# Define POST variables
uname = request.POST['username']
passwd = request.POST['password']
# SQL query vulnerable to SQLi
sql = "SELECT id FROM users WHERE username='" + uname + "' AND password='" + passwd + "'"
# Execute the SQL statement
database.execute(sql)
这些输入字段容易受到SQL注入的攻击。攻击者可能以改变数据库服务器执行的SQL语句的方式在输入中使用SQL命令。例如,他们可以使用涉及单引号的技巧,并将passwd
字段设置为:
password' OR 1=1
结果,数据库服务器运行以下SQL查询:
SELECT id FROM users WHERE username='username' AND password='password' OR 1=1'
由于该OR 1=1
语句,无论and是什么,该WHERE
子句都id
从users
表中返回第一个。数据库中的第一个用户通常是管理员。这样,攻击者不仅绕过身份验证,而且还获得了管理员特权。他们还可以注释掉其余的SQL语句,以进一步控制SQL查询的执行:username
password
id
-- MySQL, MSSQL, Oracle, PostgreSQL, SQLite
' OR '1'='1' --
' OR '1'='1' /*
-- MySQL
' OR '1'='1' #
-- Access (using null characters)
' OR '1'='1' %00
' OR '1'='1' %16
基于联合的SQL注入示例
SQL注入的最常见类型之一是使用UNION运算符。它使攻击者可以将两个或多个SELECT语句的结果合并为一个结果。该技术称为基于联合的SQL注入。
以下是此技术的示例。它使用网页testphp.vulnweb.com,这是由Acunetix托管的故意易受攻击的网站。
以下HTTP请求是合法用户将发送的普通请求:
GET http://testphp.vulnweb.com/artists.php?artist=1 HTTP/1.1
Host: testphp.vulnweb.com
该artist
参数容易受到SQL注入的攻击。以下有效payload修改了查询以查找不存在的记录。它将URL查询字符串中的值设置为-1
。当然,它可以是数据库中不存在的任何其他值。但是,负值是一个很好的猜测,因为数据库中的标识符很少是负数。
在SQL Injection中,UNION
运算符通常用于将恶意SQL查询附加到打算由Web应用程序运行的原始查询。注入查询的结果将与原始查询的结果结合在一起。这使攻击者可以从其他表中获取列值。
GET http://testphp.vulnweb.com/artists.php?artist=-1 UNION SELECT 1, 2, 3 HTTP/1.1
Host: testphp.vulnweb.com
下面的示例显示如何使用SQL Injection有效负载从这个故意易受攻击的站点获取更多有意义的数据:
GET http://testphp.vulnweb.com/artists.php?artist=-1 UNION SELECT 1,pass,cc FROM users WHERE uname='test' HTTP/1.1
Host: testphp.vulnweb.com
如何防止SQL注入
防止SQL注入攻击的唯一可靠方法是输入验证和参数化查询(包括准备好的语句)。应用程序代码永远不要直接使用输入。开发人员必须清除所有输入,而不仅仅是登录表单之类的Web表单输入。他们必须删除潜在的恶意代码元素,例如单引号。关闭生产站点上数据库错误的可见性也是一个好主意。数据库错误可与SQL Injection一起使用,以获取有关数据库的信息。
如果发现SQL注入漏洞(例如使用Acunetix扫描),则可能无法立即修复。例如,该漏洞可能位于开放源代码中。在这种情况下,您可以使用Web应用程序防火墙临时清理您的输入。
如何防止SQL注入(SQLi)–通用技巧
防止SQL注入漏洞并不容易。具体的防护技术取决于SQLi漏洞的子类型,SQL数据库引擎和编程语言。但是,为了确保Web应用程序的安全,应遵循某些一般性的战略原则。
步骤1:训练和维持意识为了确保您的Web应用程序安全,参与构建Web应用程序的每个人都必须意识到与SQL注入相关的风险。您应该为所有开发人员,质量检查人员,DevOps和SysAdmins提供适当的安全培训。您可以通过将他们引至此页面开始。 |
|
第2步:不要相信任何用户输入将所有用户输入视为不可信。SQL查询中使用的任何用户输入都会带来SQL注入的风险。对待经过身份验证的用户和/或内部用户的输入的方式与对待公共输入的方式相同。 |
|
步骤3:使用白名单,而不是黑名单不要基于黑名单过滤用户输入。聪明的攻击者几乎总是会找到一种方法来规避您的黑名单。如果可能,请仅使用严格的白名单验证和过滤用户输入。 |
|
步骤4:采用最新技术较早的Web开发技术没有SQLi保护。使用最新版本的开发环境和语言以及与该环境/语言关联的最新技术。例如,在PHP中使用PDO代替MySQLi。 |
|
步骤5:采用经过验证的机制不要尝试从头开始构建SQLi保护。大多数现代开发技术都可以为您提供防止SQLi攻击的机制。使用此类机制,而不要尝试重新发明轮子。例如,使用参数化查询或存储过程。 |
|
步骤6:定期扫描(使用Acunetix)SQL注入可以由您的开发人员或通过外部库/模块/软件引入。您应该定期使用Web漏洞扫描程序(例如Acunetix)扫描Web应用程序。如果使用Jenkins,则应安装Acunetix插件以自动扫描每个版本。 |
本文始发于微信公众号(利刃信安):什么是SQL注入(SQLi)以及如何防止它
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论