--更新 01/03 02:12AM--
发现代码中并无出奇, 只是将几年前的冷饭再炒.因为多年过去了, 可能有人疏忽, 多试一些总有人中招的.
注入方式中数字字段是最容易进入的. 文本也可以, 但在QUERYSTRING中提交文本的情况不如数字多.
最常见的就是形如 news.asp?id=3
在ASP中,疏忽的写法为
aspID=request("id")
SQL="SELECT * FROM NEWS WHERE ID=" & aspID
SET RS=Conn.EXEC(SQL)
这里的ID完全没有保护, 如果ID是一个字符串, 很容易就注入了
例如ID=3;delete%20from%20news;
直接删除NEWS表记录
对于文本来说, 例如news.asp?keyword=abc
aspKeyword=request("keyword")
SQL="SELECT * FROM NEWS WHERE TITLE LIKE '%" &aspKeyword& "%'
注入时就用在KEYWORD里用单引号封住, 最后再写一句假的SQL来骗原代码.
例如 keyword=abc';delete from news;select * from sysobject where SOMETHING LIKE '%
相比ID当然就麻烦的多.
下面的内容中的一大堆代码, 其实是为了避开防注入程序中限制的一些关键字.
看了几个防注入程序, 一般是通过过滤的方法, 例如
SQL_injdata = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|daxia123|''')
FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
修复代码 by 水上飞云@ http://bbs.ikaka.com/showtopic-8580913-4.aspx#9261365
注:对ntext,text 无效
/***********定义要去除的字符,请注意,
可能不止一条,我的服务器就查到两条************/
declare @delStr nvarchar(500)
set @delStr=''
/****************************************/
/**********以下为操作实体************/
set nocount on
declare @tableName nvarchar(100),@columnName nvarchar(100),@tbID
int,@iRow int,@iResult int
declare @sql nvarchar(500)
set @iResult=0
declare cur cursor for
select name,id from sysobjects where xtype='U'
open cur
fetch next from cur into @tableName,@tbID
while @@fetch_status=0
begin
declare cur1 cursor for
--xtype in (231,167,239,175) 为char,varchar,nchar,nvarchar类型
select name from syscolumns where xtype in (231,167,239,175)
and id=@tbID
open cur1
fetch next from cur1 into @columnName
while @@fetch_status=0
begin
set @sql='update [' + @tableName + '] set ['+ @columnName +']=
replace(['+@columnName+'],'''+@delStr+''','''') where
['+@columnName+'] like ''%'+@delStr+'%'''
exec sp_executesql @sql
set @iRow=@@rowcount
set @iResult=@iResult+@iRow
if @iRow>0
begin
print 'Table: '+@tableName+', Column:'+@columnName+' has been
updated with '+convert(varchar(10),@iRow)+' record(s);'
end
fetch next from cur1 into @columnName
end
close cur1
deallocate cur1
fetch next from cur into @tableName,@tbID
end
print 'The database has '+convert(varchar(10),@iResult)+' record(s)
been updated.'
close cur
deallocate cur
set nocount off
/*****以上为操作实体******/
相关建议 by xutingxin @ http://bbs.ikaka.com/showtopic-8580913-5.aspx#9261798
解决办法:1 严格过滤 request.form 和 request.querystring 获取的内容,坚决不用 request("name") 这样的方式获取值,凡是采用 cookies 保存的内容,尽量不要用在sql语句里进行查询数据库操作;2 重要的用户资料尽量采用 session 验证,因为session是服务器端的,客户端无法伪造数据,除非他有你服务器的权限。
可以采用以下的防范 get 、post以及cookies 注入的代码来过滤 sql 注入攻击:
<%
Response.Buffer = True '缓存页面
'防范get注入
If Request.QueryString <> "" Then StopInjection(Request.QueryString)
'防范post注入
If Request.Form <> "" Then StopInjection(Request.Form)
'防范cookies注入
If Request.Cookies <> "" Then StopInjection(Request.Cookies)
'正则子函数
Function StopInjection(Values)
Dim regEx
Set regEx = New RegExp
regEx.IgnoreCase = True
regEx.Global = True
regEx.Pattern = "'|;|#|([/s/b+()]+([email=select%7Cupdate%7Cinsert%7Cdelete%7Cdeclare%7C@%7Cexec%7Cdbcc%7Calter%7Cdrop%7Ccreate%7Cbackup%7Cif%7Celse%7Cend%7Cand%7Cor%7Cadd%7Cset%7Copen%7Cclose%7Cuse%7Cbegin%7Cretun%7Cas%7Cgo%7Cexists)[/s/b]select|update|insert|delete|declare|@|exec|dbcc|alter|drop|create|backup|if|else|end|and|or|add|set|open|close|use|begin|retun|as|go|exists)[/s/b[/email]+]*)"
Dim sItem, sValue
For Each sItem In Values
sValue = Values(sItem)
If regEx.Test(sValue) Then
Response.Write ""
Response.End
End If
Next
Set regEx = Nothing
End function
%>
把以上的代码另存为一个文件,如 antisql.asp ,然后在数据库连接文件开头包含这个文件 ,就可以实现全站的防范 sql 注入的攻击了。