Navicat 博客

在数据库层面上防止 SQL 注入 2021 年 4 月 14 日,由 Robert Gravelle 撰写

许多组织通过在其应用程序中实施输入验证来致力保护其数据。事实上,大多数网络攻击直接针对数据库服务器本身,而应用程序安全性根本没有发挥作用!作为一个数据库管理员(DBA)或数据库开发人员,你具有强大的能力来降低网络攻击的风险和/或由此造成的损害,包括最常见的网络攻击形式:SQL 注入。在今天的文章中,我们将探索一些可以大大减少遭受 SQL 注入攻击的做法。

将所有数据库逻辑放在存储过程中

恶意实体越容易将未经过滤的 SQL 传递给数据库服务器,数据就更容易丢失或被盗。通过将所有查询和数据操纵语句(DML)放在存储过程中,可以使黑客更难发出 DML 语句。

以下代码示例使用 CallableStatement(Java 对存储过程接口的实现)执行相同的数据库查询:

String custname = request.getParameter("customerName");
try {
  CallableStatement cs = connection.prepareCall("{call sp_getCustomerAccount(?)}");
  cs.setString(1, custname);
  ResultSet results = cs.executeQuery();
  // ...result set handling
} catch (SQLException se) {
  // ...logging and error handling
}

将输入验证列入白名单

用户提供的值不是用于绑定数据库实体,例如表、列名,甚至排序顺序指示器(ASC 或 DESC)。这些值应来自你自己的 SQL 代码,而不应来自用户参数。为了定位特定的表名和列名,参数值应映射到合法(预期)的表名和/或列名,以防止未经验证的用户输入最终出现在查询中。

以下是表名验证的示例:

String tableName;
switch(PARAM):
  case "Value1": tableName = "clientTable";
                 break;
  case "Value2": tableName = "employeeTable";
                 break;
  ...
  default      : throw new InputValidationException("unexpected value provided"
                                                  + " for table name");

对于诸如排序顺序之类的简单内容,一种解决方案是接受用户提供的输入作为布尔值(boolean),然后将其用于选择要附加到查询的安全值。实际上,这是动态查询构造中的一种常见做法。

public String myMethod(boolean sortOrder) {
  String SQLquery = "some SQL ... order by Salary " + (sortOrder ? "ASC" : "DESC");
  ...

将所有用户提供的输入进行转义或清除

只有当以上的方法都不可行时,才应使用用户输入转义。与其他防御相比,此防御被认为是比较弱,原因是无法保证它防止在每一种可能的情况下所有的 SQL 注入。

将用户输入的转义与特定的数据库类型相匹配至关重要,因为每个 DBMS 都支持某些类型查询特定的一个或多个字符转义方案。为特定数据库使用正确的转义方案对所有用户提供的输入进行转义,那么 DBMS 不会将用户输入与开发人员编写的 SQL 代码混淆,从而避免了任何可能的 SQL 注入漏洞。

OWASP Enterprise Security API (ESAPI) 是一个免费、开源的、网页应用程序安全控件库,它使程序员可以更轻松地增强其应用程序免受网络攻击。ESAPI 库被设计来使程序员能够更容易在现有的程序中引入安全因素。

使用 ESAPI 数据库编解码器是非常简单。以下是一个 Oracle 的示例:

ESAPI.encoder().encodeForSQL( new OracleCodec(), queryparam );

总结

作为一个数据库管理员(DBA)或数据库开发人员,你具有强大的能力来降低网络攻击的风险和/或由此造成的损害,包括最常见的网络攻击形式:SQL 注入。按照今天概述的做法进行操作,可以大大减少遭受 SQL 注入攻击的可能性。


Rob Gravelle 居住在加拿大渥太华,是一名有 20 多年经验的 IT 专家。过往,Rob 曾为与情报有关的组织(如加拿大边境服务局和各种商业组织)构建系统。如果你想雇用 Rob,可以发送电子邮件至 rgconsulting(AT)robgravelle(DOT)com。在业余时间,Rob 是一名出色的吉他演奏家,并发行了几张 CD

Navicat 文章
频道条目
分享
文章归档