一样平常 用户在登岸 时,体系 会要求输入用户名及暗码 ,然后将这些数据传输到指定页,举行 验证,大抵 的代码如下:
Set Conn= Server.CreateObject("ADODB.Connection") '界说 毗连 数据库的对象
Const AccessFile="jmdcw.mdb" '数据库地点
Conn.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" Server.MapPath(AccessFile) '毗连 到数据库
Conn.Open '打开数据库
....................
name=request("name") '得到所提交的用户名
pass=request("pass") '得到所提交来的暗码
............
Set Jmdcw=Server.CreateObject("ADODB.RecordSet") '界说 操纵 数据库的对象
SQL="SELECT username,userpass FROM User WHERE username='"name"' AND userpass='"pass"'" 'SQL语句
Jmdcw.Open SQL,Conn,1,1 '实行 查询
......
If Jmdcw.EOF AND Jmdcw.BOF Then '假如 没有查询到
response.redirect ".html" '表现 错误页
end if
'假如 精确 ,就继承 实行 。
..........
以上就是一段简单 的用户验证代码 ,当注入弊端 被广泛发掘之后,雷同 如许 的弊端 就越来越少了,但少并不表现 程序员在写代码时已经具备了防范意识 ,偶然 之中还是 会出现如许 或那样的弊端 。OK,书归正传,先来测试一下上面的代码。输入的用户名是:jmdcw ,暗码 是:123456。(典范 的弱口令暗码 ,哈哈),如许 SQL语句就是:
select username,userpass from user where username='jmdcw' and userpass='123456'
程序会查询user表中是否有jmdcw用户 ,而且 该用户的暗码 是否为123456 。假如 username='jmdcw'的结果 为真,userpass='123456'的结果 也为真,那么“真 And 真 ”的结果 就是真 ,验证通过。
固然 ,假如 用户名和暗码 此中 之一的结果 为假,“真 And 假 ”的结果 就是假,固然 “ 假 And 假 ”的结果 也是假 ,呵呵。
没有效 户名或暗码 怎么进入?试一下'or''='吧,在提交用户名处输入 jmdcw'or''=',如许 的SQL语句就是
select username,userpass from user where username='jmdcw'or''='' and userpass='12345678'
在逻辑表达式中 ,AND的优先级要高于OR,以是 语句会先对 “''='' and userpass='12345678'” 举行 判定 ,固然 ''='' 为真 ,但暗码 为假,以是 结果 为假,但由于 我们参加 了OR毗连 符 ,如许 ,固然 背面 的结果 为假,但username的结果 为真 ,以是 也一样能进入这个用户的背景 。
但假如 不知道用户的名称,那么就要在输入的暗码 后也参加 一个'or''=',如许 ,SQL语句就是
select username,userpass from user where username='jmdcw11'or''='' and userpass='12345678'or''=''
在实行 and语句 ,''='' and userpass='12345678'的结果 为假,然后是 'jmdcw11'or假 ,结果 为假 ,再接下来是:假or ''='',这个结果 就是真了。
但如今 的暗码 都用MD5加密,对提交来的暗码 在进入SQL语句之前 ,先用MD5举行 了转换,如许 ,就算在暗码 后参加 了'or''=' ,也发挥不了作用。对于暗码 采取 md5加密的,不妨在用户名处再参加 一个or''='',也 就是在用户名处输入:jmdcw'or''=''or''=' ,如许 的SQL 语句就是:
select username,userpass from user where username='jmdcw11'or''=''or''='' and userpass='12345678'
先实行 and语句,结果 为假,然后是username='jmdcw11'or''='',结果 为真 ,接下来是:真or假,结果 还是 真,如许 又绕过了验证 。
说到这儿 ,我忽然 想起,在文章开头所提到的网站,其暗码 也是用md5加密的 ,而且 我也不知道任何一个用户名,也只用了一个or语句,为什么却进入了呢?思来思去 ,莫不是SQL语句中的用户与暗码 的位置有所差别 ,其的SQL语句是如许 的:
select username,userpass from user where WHERE userpass='"pass"'" and username='"name"',
暗码 在前面 ,用户在背面 ,如许 ,当我在用户名处输入:jm'or''='后,其语句就变成 了
select username,userpass from user where WHERE userpass='123456" and username='jm'or''=''
按照优先级 ,先运算ANd语句,结果 为假,然后是OR语句 ,假or''='',结果 就是真了。看来代码中的位置发生变革 也能演绎成一种弊端 。
上面所提到的方法重要 是针对于ACCESS数据库,但假如 程序所对应的数据库是SQL ,那危害就大很了,先不要说别的,还是 说一下登岸 的事变 ,直接用:
存在的用户名';--
这个可以不消 暗码 就登岸 到指定的用户之中,假如 不知道呢:就用:
恣意 名称'or''='';--
如许 所进入的会是第一个用户,很有大概 是管理员的用户之中.
怎样 防止这种弊端 呢?很简单 ,就是在吸取 字符的语句中参加 replace过滤语句,比如 name就是:
name=replace(request("name"),"'","")
将'过滤为空 。暗码 过滤的方法也雷同 。固然 ,这是简单 的过滤方法,尚有 更多复杂的。比如 过滤一些特别 字符,空格 、chr(0)、%、等一些字符,防止写入XSS代码 。