1SELECT * FROM user WHERE username='zoumiaojiang' OR 1 = 1 这条 SQL 语句的查询条件永远为真,所以意思就是恶意攻击者不用我的密码,就可以登录进我的账号,然后可以在里面为所欲为,然而这还只是最简单的注入,牛逼的 SQL 注入高手甚至可以通过 SQL 查询去运行主机系统级的命令,将你主机里的内容一览无余,这里我也没有这个能力讲解的太深入,毕竟不是专业研究这类攻击的,但是通过以上的例子,已经了解了 SQL 注入的原理,我们基本已经能找到防御 SQL 注入的方案了 。如何预防 SQL 注入防止 SQL 注入主要是不能允许用户输入的内容影响正常的 SQL 语句的逻辑,当用户的输入的信息将要用来拼接 SQL 语句的话,我们应该永远选择不相信,任何内容都必须进行转义过滤,当然做到这个还是不够的,下面列出防御 SQL 注入的几点注意事项:
- 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害
- 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理 。
- 对进入数据库的特殊字符(',",,<,>,&,*,; 等)进行转义处理,或编码转换 。基本上所有的后端语言都有对字符串进行转义处理的方法,比如 lodash 的 lodash._escapehtmlchar 库 。
- 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句 。例如 Node.js 中的 MySQLjs 库的 query 方法中的 ? 占位参数 。
1mysql.query(`SELECT * FROM user WHERE username = ? AND psw = ?`, [username, psw]); - 在应用发布之前建议使用专业的 SQL 注入检测工具进行检测,以及时修补被发现的 SQL 注入漏洞 。网上有很多这方面的开源工具,例如 sqlmap、SQLninja 等 。
- 避免网站打印出 SQL 错误信息,比如类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入 。
- 不要过于细化返回的错误信息,如果目的是方便调试,就去使用后端日志,不要在接口上过多的暴露出错信息,毕竟真正的用户不关心太多的技术细节,只要话术合理就行 。
命令行注入命令行注入漏洞,指的是攻击者能够通过 HTTP 请求直接侵入主机,执行攻击者预设的 shell 命令,听起来好像匪夷所思,这往往是 Web 开发者最容易忽视但是却是最危险的一个漏洞之一,看一个实例:
假如现在需要实现一个需求:用户提交一些内容到服务器,然后在服务器执行一些系统命令去产出一个结果返回给用户,接口的部分实现如下:
12345// 以 Node.js 为例,假如在接口中需要从 github 下载用户指定的 repoconst exec = require('mz/child_process').exec;let params = {/* 用户输入的参数 */};exec(`git clone ${params.repo} /some/path`); 这段代码确实能够满足业务需求,正常的用户也确实能从指定的 git repo 上下载到想要的代码,可是和 SQL 注入一样,这段代码在恶意攻击者眼中,简直就是香饽饽 。如果 params.repo 传入的是
https://github.com/zoumiaojiang/zoumiaojiang.github.io.git 当然没问题了 。
可是如果 params.repo 传入的是
https://github.com/xx/xx.git && rm -rf /* && 恰好你的服务是用 root 权限起的就惨了 。
具体恶意攻击者能用命令行注入干什么也像 SQL 注入一样,手法是千变万化的,比如「反弹 shell 注入」等,但原理都是一样的,我们绝对有能力防止命令行注入发生 。防止命令行注入需要做到以下几件事情:
- 后端对前端提交内容需要完全选择不相信,并且对其进行规则限制(比如正则表达式) 。
- 在调用系统命令前对所有传入参数进行命令行参数转义过滤 。
推荐阅读
- 痔疮发作怎么办
- 痔疮出血怎么办
- 银屑病的治疗
- 抑郁症有哪些症状
- 毛囊炎传染吗
- 如何使用复印机,如何处理复印过程中的常见问题
- 100种常见室内绿植,常见佛珠材质的五行划分
- Winserver2019 web服务器使用自签名证书进行https加密域名访问
- Winserver 2019 搭建web服务器
- Linux系统安全攻防技术
