防御 SQL 注入攻击

简介: SQL注入可在应用层和网络层检测防御。应用层防御主要包括输入验证(白名单更安全)和使用参数化查询防止恶意SQL构造。同时应过滤敏感字符、处理错误信息,避免泄露数据库细节,提升安全性。

SQL 注入攻击可以在应用程序流量中的两个位置被检测到并可能被阻止:应用程序中和网络中。
应用中的防御
应用程序可以通过多种方式防御 SQL 注入攻击。主要方法包括以白名单或黑名单的形式验证用户提供的数据,以及构建 SQL 语句以使用户提供的数据不会影响语句的逻辑。
黑名单和白名单
在应用程序本身中,有两种输入验证方法可以防御 SQL 注入攻击:黑名单和白名单。
通过黑名单,可以从用户输入中删除或替换特定的已知恶意字符。尽管这种方法经常被实施,主要是因为它很容易实现,但与白名单相比,它并不有效。黑名单可能无法正确处理复杂的混淆,这可能允许攻击者破坏过滤器并可能注入 SQL 语句。这种失败通常是由于不断发展的攻击技术和过滤器不全面或未正确实施而导致的。
或者,白名单根据允许的字符列表检查每条用户输入。这种方法可以更有效地降低 SQL 注入的风险,因为它对允许的输入类型有更多的限制。实施良好的白名单应根据预期的数据格式检查用户提供的每条数据。
无论采用哪种方法,很可能都需要根据输入字段类型或输入字段类别(例如文本或数字数据)来定制允许的字符。用于过滤 SQL 注入启用字符的输入验证和清理功能可能会被泛化并用于过滤表明跨站点脚本攻击的字符。有关跨站点脚本的更多信息,请参阅应用智能白皮书 了解跨站点脚本 (XSS) 威胁向量。
当应用程序从用户接收到无效字符时,它必须确定性地采取行动。根据处理意外数据的情况及其可能产生的影响,不同级别的响应可能是适当的。例如,应用程序应明确拒绝提交两个破折号字符 (--) 或分号字符 (;) 作为登录名或密码一部分的用户,并且应向应用程序管理员发送高严重性警报。然而,当应用程序收到单个撇号字符作为由输入包裹运输信息的经过身份验证的用户提交的街道地址的一部分时,这种有点严厉的响应可能不合适。尽管如此,应用程序应该按预期运行,
输入验证和清理的实现应包含警报功能。当收到意外输入时,此功能应向应用程序管理或开发团队发出警报,因为它可能表明过滤器可能错误地阻止了有效但意外的数据,或者应用程序可能受到攻击。无论哪种情况,都可能需要更改应用程序的过滤功能。
乍一看,这些数据验证和清理技术似乎可以在客户端 JavaScript 中实现,并在用户的浏览器中运行。然而,从安全角度来看,必须假设任何和所有类型的数据都将源自用户的浏览器,无论客户端施加的保护措施如何。尽管如此,客户端数据验证技术可以增强应用程序的可用性。
强化 SQL 语句
除了严格的输入验证之外,还应综合使用 ASP.NET 中的参数化查询、Java 中的准备语句或其他语言中的类似技术。在将 SQL 语句传递到底层数据库系统之前,每种技术都会执行所有必需的危险字符转义。
以下示例描述了 Java 中准备好的语句的使用,并说明了如何在没有用户提供的数据的情况下构建 SQL 语句,然后以无法更改 SQL 语句的结构和意图的方式使用数据进行扩充:

String sql = "select * from Users where (用户名 = ? 和密码 = ?)";

// 准备语句
prepareStmt = connection.prepareStatement(sql);
preparedStmt.setString(1, 提交的用户名);
preparedStmt.setString(2, 提交密码);

// 结果
preparedStmt.executeQuery();
请注意,准备好的陈述和类似技术并不是万能药;如果在没有绑定变量的情况下错误地使用它们,它们并不比传统构造的动态查询更安全。以下示例说明了 Java 中预准备语句的错误使用:
String sql = "select * from Users where (用户名 = '" + SubmittedUsername +
"' 和密码 = '" + SubmittedPassword + "')"; 准备语句prepareStmt = connection.prepareStatement(sql); 结果 = preparedStmt.executeQuery();
除了确保 SQL 语句的意图不会被用户提供的数据更改之外,应用程序还应该在 SQL 生成的错误消息到达最终用户之前捕获并删除它们。尽管这种保护措施可能会妨碍开发人员排除应用程序错误的能力(可以通过额外的后端日志记录轻松克服这种错误),但 SQL 错误的呈现将极大地帮助攻击者成功利用 SQL 注入漏洞。以下示例是一个过于冗长的错误消息:
com.mysql.jdbc.DBException。MySQL SyntaxErrorException:table“ sqlInjectionTest .test” doesn't exists
at com.mysql.jdbc.SQLError.createSQLException( SQLError.java:936 )
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3206)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1232)
at sqlInjectionBefore.main(before.java:28)
此错误消息表明应用程序正在使用 Java 编程语言和 MySQL 数据库平台,并且查询的数据库名为“sqlInjectionTest”。每条信息都可以帮助攻击者制作他们的应用程序输入,这增加了他们成功的几率。

相关文章
|
SQL XML Java
程序员都要懂的SQL防注入Mybatis框架SQL防注入
程序员都要懂的SQL防注入Mybatis框架SQL防注入
355 0
|
9月前
|
XML JSON Java
HttpServletRequest 的三个方法request.getParameter()、request.getInputStream()、request.getReader()
在 Java Web 开发中,HttpServletRequest 是处理 HTTP 请求的接口,提供了多种方法用于获取客户端请求的不同类型的数据。三种常见的方法是 getParameter()、getInputStream() 和 getReader()。它们各自的作用和使用场景有所不同,下面详细解释这三个方法的区别与应用。
1034 4
|
Ubuntu Linux
在Linux中,如何添加路由?
在Linux中,如何添加路由?
|
存储 搜索推荐 关系型数据库
ElasticSearch 详解
ElasticSearch 是一款优秀的开源搜索引擎,适用于大数据场景下的高效检索与分析。其分布式架构、实时搜索和灵活的数据分析功能使其能处理 PB 级数据量。相比 Solr,ES 在实时性、分布式架构和文档处理上更具优势。核心概念包括索引、文档、分片和副本等。ES 使用倒排索引实现快速搜索,区别于正向索引。与关系型数据库相比,ES 更适合非结构化数据和全文搜索。总结来说,ES 在电商搜索、日志分析等领域有广泛应用,未来有望带来更多创新。
686 19
|
运维 监控 Linux
探究-ping指令的使用
【9月更文挑战第2天】`ping` 指令是网络诊断工具,通过发送 ICMP 回显请求并接收应答,测试网络连接的可达性和响应时间。在 Windows、Linux 和 macOS 中均可使用。主要参数包括 `-t`(持续监测)、`-n`(指定次数)和 `-l`(数据包大小)。结果分析关注回显时间、数据包丢失率和 TTL 值,适用于网络故障排查、性能评估和服务器监控。掌握 `ping` 的使用方法可帮助管理和优化网络连接。
3045 3
|
前端开发 Java Spring
Spring MVC核心:深入理解@RequestMapping注解
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的核心,它将HTTP请求映射到控制器的处理方法上。本文将深入探讨`@RequestMapping`注解的各个方面,包括其注解的使用方法、如何与Spring MVC的其他组件协同工作,以及在实际开发中的应用案例。
757 4
|
存储 负载均衡 网络协议
BGP 技术连载:BGP 选路规则
【4月更文挑战第23天】
1496 0
|
网络协议 安全 Unix
什么是 Banner 抓取和 OS 指纹识别?
【8月更文挑战第31天】
711 0
|
机器学习/深度学习 算法 数据挖掘
一文介绍回归和分类的本质区别 !!
一文介绍回归和分类的本质区别 !!
1516 1
|
机器学习/深度学习 Java
机器学习中的召回率与准确率详解
机器学习中的召回率与准确率详解

热门文章

最新文章