【Security】SQL Injection

Posted by 西维蜀黍 on 2023-01-11, Last Modified on 2023-05-02

SQL 注入(SQL Injection)

Overview

A SQL injection attack consists of insertion or “injection” of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to affect the execution of predefined SQL commands.

SQL 注入漏洞(SQL Injection)是 Web 开发中最常见的一种安全漏洞。可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。

而造成 SQL 注入的原因是因为程序没有有效的转义过滤用户的输入,使攻击者成功的向服务器提交恶意的 SQL 查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。

很多 Web 开发者没有意识到 SQL 查询是可以被篡改的,从而把 SQL 查询当作可信任的命令。殊不知,SQL 查询是可以绕开访问控制,从而绕过身份验证和权限检查的。更有甚者,有可能通过 SQL 查询去运行主机系统级的命令。

SQL 注入原理

下面将通过一些真实的例子来详细讲解 SQL 注入的方式的原理。

考虑以下简单的管理员登录表单:

<form action="/login" method="POST">
    <p>Username: <input type="text" name="username" /></p>
    <p>Password: <input type="password" name="password" /></p>
    <p><input type="submit" value="登陆" /></p>
</form>

后端的 SQL 语句可能是如下这样的:

let querySQL = `
    SELECT *
    FROM user
    WHERE username='${username}'
    AND psw='${password}'
`;
// 接下来就是执行 sql 语句...

目的就是来验证用户名和密码是不是正确,按理说乍一看上面的 SQL 语句也没什么毛病,确实是能够达到我们的目的,可是你只是站在用户会老老实实按照你的设计来输入的角度来看问题,如果有一个恶意攻击者输入的用户名是 zoumiaojiang' OR 1 = 1 --,密码随意输入,就可以直接登入系统了。WFT!

冷静下来思考一下,我们之前预想的真实 SQL 语句是:

SELECT * FROM user WHERE username='zoumiaojiang' AND psw='mypassword'

可以恶意攻击者的奇怪用户名将你的 SQL 语句变成了如下形式:

SELECT * FROM user WHERE username='zoumiaojiang' OR 1 = 1 --' AND psw='xxxx'

在 SQL 中,-- 是注释后面的内容的意思,所以查询语句就变成了:

SELECT * FROM user WHERE username='zoumiaojiang' OR 1 = 1

这条 SQL 语句的查询条件永远为真,所以意思就是恶意攻击者不用我的密码,就可以登录进我的账号,然后可以在里面为所欲为,然而这还只是最简单的注入,牛逼的 SQL 注入高手甚至可以通过 SQL 查询去运行主机系统级的命令,将你主机里的内容一览无余,这里我也没有这个能力讲解的太深入,毕竟不是专业研究这类攻击的,但是通过以上的例子,已经了解了 SQL 注入的原理,我们基本已经能找到防御 SQL 注入的方案了。

How to prevent

parameterized SQL statements /Prepared statement

With most development platforms, parameterized statements that work with parameters can be used (sometimes called placeholders or bind variables) instead of embedding user input in the statement. A placeholder can only store a value of the given type and not an arbitrary SQL fragment. Hence the SQL injection would simply be treated as a strange (and probably invalid) parameter value. In many cases, the SQL statement is fixed, and each parameter is a scalar, not a table. The user input is then assigned (bound) to a parameter

Ref

strict input validation rules

Pattern check

Integer, float or boolean, string parameters can be checked if their value is valid representation for the given type. Strings that must follow some strict pattern (date, UUID, alphanumeric only, etc.) can be checked if they match this pattern.

Object relational mappers

Developers can use ORM frameworks such as Hibernate[20] to create database queries in a safe and developer-friendly way. Since database queries are no longer constructed as strings, there is no danger of an injection vulnerability

Types of SQL Injections

In-band SQLi

The attacker uses the same channel of communication to launch their attacks and to gather their results. In-band SQLi’s simplicity and efficiency make it one of the most common types of SQLi attack. There are two sub-variations of this method:

  • Error-based SQLi—the attacker performs actions that cause the database to produce error messages. The attacker can potentially use the data provided by these error messages to gather information about the structure of the database.
  • Union-based SQLi—this technique takes advantage of the UNION SQL operator, which fuses multiple select statements generated by the database to get a single HTTP response. This response may contain data that can be leveraged by the attacker.

Reference