开发Web应用程序时,不可避免的安全措施是不可避免的。其中,“ SQL注入”被称为对数据库的严重威胁。
在本文中,一种易于理解的方式解释SQL注入的工作原理,并演示如何实际进行攻击。此外,和Code安全实现这对于Web开发人员来说是必读的,从初学者到中级玩家。
什么是SQL注入?通过视频体验攻击的危险!
SQL注入是一种使用应用程序中使用漏洞的攻击,以在数据库上启动欺诈操作。
即使您发现它“看起来有些困难……”,您也可以通过观看下面的简短视频来大致了解它是什么样的攻击!
📺在YouTube上观看演示:链接中观看
该视频解释了SQL注入如何使用简单的示例工作。
请看一下,然后前往下一部分以了解更多信息!
什么是SQL注入?
一种攻击技术,当应用程序与数据库互动,从而导致攻击者执行非法操作。
- 未经授权的数据获取:用户信息和敏感数据可能会泄漏。
- 绕过身份验证:攻击者可能能够未经授权登录。
- 数据篡改和删除:数据库被操纵,可靠性受到损害。
SQL注入如何在具体示例中起作用
登录功能说明了其工作原理。例如,对于以下参数,SQL被这样转换为:
- 用户名:
管理员
- 密码:
密码
从用户中选择count(*)> 0,其中用户名='admin'和password ='password';
这是正常行为,但是如果攻击者输入这样的东西会发生什么:
- 用户名:
'或'1'='1' -
- 密码:
任何值
可以按照以下方式重写:
从用户中选择count(*)> 0,其中用户名='''或'1'='1' - 和password ='任何值';
结果: - 密码='任何值'
由-
评论或'1'='1
始终是正确的,因此所有用户都被认为是经过身份验证的,并且可以未经授权的登录。
如何处理SQL注入
SQL注射是对应用程序安全的严重威胁。但是,采取适当的措施可以有效减轻这种风险。
这次,我们将解释如何使用Spring Boot和Mybatis通过利用这些工具来了解如何构建安全应用程序。
1。使用占位符的参数化查询
摘要:使用占位符(#{})安全地绑定参数,而不是将用户输入直接嵌入到SQL语句中。
原因:占位符自动逃脱输入值并防止SQL注入。
以下是使用未使用的占位符和代码的代码。
差异是“'$ {username}'→#{username}'”和“'$ {password}'→#{password}'”。
在Mybatis的情况下,您可以通过将其设置为#{}
如果要使用SQL中的参数,请确保使用#{}
易受伤害的
@Select(“ select count(*)> 0从用户中的用户='$ {username}'和password ='$ {password}'”)boolean vileean vileanableAuthenticate(@param(@param( @username'userName“)字符串userName,@param(@param(@param)( @parem @parem(pary))字符串password);
安全
@Select(“选择count(*)> 0从用户中的用户=#{username}和password =#{password}”)boolean secureauthenticate(@param(@param(“ username”)字符串用户名,@param(param(“ passworm”)
2。用户输入的验证和消毒
摘要:限制用户可以输入的类型和格式,以防止非法输入。
原因:删除危险的字符串和SQL关键字可以大大降低攻击的成功率。
限制参数的字符类型和格式,或删除或逃脱特定的字符(例如'
, -
, ;
等)以避免SQL注入。
如果(!username.matches(“^[a-za-z0-9]+$”)){抛出新的illegalargumentException(“无效输入”); }
基本上,最好考虑“ 1。使用占位符的参数化查询”,但是如果不可能,则该解决方案可以显着降低攻击的成功率。
3。避免构建动态查询
摘要:使用参数化查询,而不是通过字符串操作动态生成SQL语句。
原因:用弦操作构建SQL使SQL注入更有可能。
这与对策有点不同,但我相信最好了解
,在组装动态SQL时使用字符串操作(+ oterator or string.format)会导致SQL注入风险。
Mybatis默认设计是为了避免使用字符串操作直接构建查询,因此这没问题,但是如果您在组装动态SQL时使用字符串操作,请小心。
在过去的情况下,我曾经看到过使用字符串操纵构建语句的来源,并用$ {}将其设置。
当然,在这种情况下,SQL注入的可能性会增加。
public String buildwhereClause(字符串用户名,字符串电子邮件){字符串whereclause =“ whene 1 = 1”;如果(用户名!= null){whereclause + =“ and username ='“ + username +”'''; } if(email!= null){whereclause + =“ and email ='” + email +“'”; }返回whereclause; } @Select(“从用户$ {whereclause}”)列表<User>findusers(@param(“ whereclause”)字符串whereclause);
在Mybatis的情况下,<if>您可以使用此选项生成动态查询,因此请确保使用此选项。
<select id="findUsers" resultType="User">从用户中选择 * 1 = 1<if test="username != null">和用户名=#{用户名}</if><if test="email != null">和电子邮件=#{电子邮件}</if></select>
4。其他
还有其他几种减少SQL注入的方法,但是重要的是要了解它并不完美,只是一种缓解措施。
- 设置最小数据库权限
- 使用存储过程
- 部署Web应用程序防火墙(WAF)
- ETC
使用Spring Boot + Mybatis实现示例
如YouTube上所述,我们提供了一个示例实现,该实现使您可以实际演示SQL注入。
整个源代码都发布在GitHub上,因此,如果需要,请检查它。
💾github存储库:此链接中检查源代码
控制器
包com.youtube.security.app.security_demo.controller;导入com.youtube.security.app.security_demo.repository.sqlindoctionmapper;导入org.springframework.web.bind.annotation.postmapping;导入org.springframework.web.bind.annotation.requestparam;导入org.springframework.web.bind.annotation.restcontroller; /** *该控制器显示了SQL注入漏洞是如何出现的,并使用 * mybatis提供了安全实现。 * * SQL注入是一种攻击,它通过将恶意SQL代码注入查询来使 *任意SQL语句成为可能。 * *安全实施示例: * - 使用占位符的参数化查询 * - >通过使用占位符(#{})而不是直接将用户输入嵌入查询中。 * - 通过限制用户可以输入的字符的类型,删除和逃避危险的字符和符号来验证和消毒用户输入 * - >提高安全性。 * - 避免使用字符串操作的动态SQL生成 * - >使用字符串操作(+ Operators and String.format)组装动态SQL时会增加SQL注入的风险。 * - >以安全的方式组装查询非常重要,而不是通过字符串操作动态生成它们。 * - > mybatis默认设计是为了避免使用字符串操纵直接构造查询的方式。 * * *该课程应仅用于教育目的。 */ @restController public Class sqlindoctionController {private final final sqlindoctionmapper sqlindoctionmapper; public sqlindoctionController(sqlindoctionmapper sqlindoctionmapper){this.sqlindoctionmapper = sqlindoctionmapper; } /***使用mybatis的脆弱查询示例。 * * @param用户名用户名 * @param密码 * @return登录结果(成功或失败) */@postmapping(“/login/login/loginable”)public String bulivnerablelogin(@requestparam string username,@requestparam username,@requestparam claste) sqlindoctionmapper.vulnerableauthenticate(用户名,密码);返回疑才能? “成功登录(脆弱的实现)”:“登录失败(脆弱的实现)”; } /***使用Mybatis运行参数化查询。 * * @param用户名用户名 * @param密码 * @return登录结果(成功或失败) */@postmapping(“/login/login/secure”)public string securelogin(@requestparam string userName,@requestparam username,@requestparam string string)返回疑才能? “成功登录(安全实施)”:“登录失败(安全实现)”; }}}
映射器
包com.youtube.security.app.security_demo.repository;导入org.apache.ibatis.annotations.mapper;导入org.apache.ibatis.annotations.param;导入org.apache.ibatis.annotations.select; @mapper public Interface sqlindoctionmapper { /***执行脆弱的SQL查询的方法。 * @param用户名 * @param密码 * @return如果身份验证成功,则为false,如果失败 */ @Select(“ select count( *)> 0,则来自用户中的用户='$ {username}'and password ='$ {passwork}'$ {passwork}'' /***执行安全SQL查询的方法。 * @param用户名用户名 * @param密码密码 * @return如果身份验证成功,则为false,如果失败 */ @select(“ select count( *) }
SQL注入的实践
我们有帮助您练习SQL注入的工具。
它可以在GitHub上找到,因此请使用它。 (即使您不使用它,也可以发送相同的请求,也没有问题。)
💾github存储库:此链接中检查源代码
以下YouTube视频展示了SQL注射攻击。这些内容使您可以亲自体验特定的攻击示例,因此请看一下。
📺在YouTube上观看演示:链接中观看
该视频演示了SQL注入攻击如何利用应用程序漏洞。这是一个简单的演示,但应该帮助您了解攻击的轮廓。