在全部漏洞类型中,SQL 注入但是说是危害最大最受你们关注的漏洞。简单说来,SQL 注入是经过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料以外结果的攻击行为。php
以 ThinkJS 为例,假设咱们写了以下一个接口(实际状况确定不会这么写的):html
// user.js module.exports = class extends think.Controller { async loginAction() { const { username, password } = this.post(); const user = await this.model().query( `SELECT * FROM user WHERE name = "${username}" AND password= "${password}"` ); if (think.isEmpty(user)) { return this.fail(); } return this.success(user); } }
当用户提交的 username
是 admin"; --
的话,最终执行的 SQL 语句就会变成mysql
SELECT * FROM user WHERE name = "admin"; --" AND password= "111"
最终攻击者就能够成功登陆 admin 帐号了,这就是最简单的 SQL 注入了。从上面这个简单示例中,咱们发现漏洞成因能够归结为如下两个缘由叠加形成的:git
SQL注入根据攻击者获取数据的方式分为回显注入、报错注入以及盲注。github
刚才演示的直接从返回结果中获取数据则为回显注入,固然也能够经过 MySQL 执行的报错结果中嗅探到数据库的结构和内容,这就是报错注入。盲注则是根据数据库执行的延时等操做来判断是否接近正确值,简单的说来有点像是拿着听诊器试探保险箱的密码的感受。web
不一样的分类原则会有不一样的分类,也有按照注入位置及方式不一样进行分类分为POST注入、GET注入、cookie注入、盲注、延时注入、搜索注入、base64注入等。sql
不过你们都支持分类形式不一样,原理仍是一致的,这里就不一一细说了。shell
若是网站存在 SQL 注入漏洞,至关于将数据库直接暴露在攻击者面前,可想而知危害会有多大了。攻击者利用 SQL 注入漏洞能实现如下攻击:数据库
从文章开头能够看到,其实漏洞的主要缘由仍是没有对用户输入的数据进行过滤,因此对来自用户的数据(GET, POST, cookie 等)最好作到如下两种过滤校验:数组
NaN
致使攻击失败。在 ThinkJS 中咱们提供了强大的 Logic 功能能够方便的对数据进行格式校验。检查输入数据格式在 ThinkJS 中还能防止另一种非通用 SQL 安全问题。文章开头的示例代码咱们在实际的应用中通常会这么写:
// user.js module.exports = class extends think.Controller { async loginAction() { const { username, password } = this.post(); const user = await this.model('user').where({ name: username, password }).find(); if (think.isEmpty(user)) { return this.fail(); } return this.success(user); } }
当咱们构造如 name=admin&password[]=!%3D&password[]=
的请求参数时,最终执行的 Model 语句就会变成
this.model('user').where({name: 'admin', password: ['!=', '']});
严格限制Web应用的数据库的操做权限,给此用户提供仅仅可以知足其工做的最低权限,从而最大限度的减小注入攻击对数据库的危害。
**请记住永远不要使用超级用户或全部者账号去链接数据库!**
当数据库被攻击时将损伤限制在当前表的范围是比较明智的选择。经过权限限制能够防止攻击者获取数据库其它信息,甚至利用数据库执行 Shell 命令等操做。
当数据库操做失败的时候,尽可能不要将原始错误日志返回,好比类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入。
除此以外,在容许的状况下,使用代码或数据库系统保存查询日志也是一个好办法。
显然,日志并不能防止任何攻击,但按期审计数据库执行日志能够跟踪是否存在应用程序正常逻辑以外的 SQL 语句执行。日志自己没用,要查阅其中包含的信息才行。毕竟,更多的信息总比没有要好。
其实在 ThinkJS 中已经将关键字处理类的方法已经集成,使用程序提供的 ORM 方法进行 SQL 构造会比本身写 SQL 语句拼接来的更方便,同时也能提升项目代码复用,减小潜在的风险。
若是对 ThinkJS 默认的 think-model 不喜欢的话,也可使用其它第三方的 ORM 框架,例如 think-sequelize。