How To: Protect From Injection Attacks in ASP.NET http://msdn2.microsoft.com/zh-cn/library/bb355989.aspx 新型 SQL 截断攻击和防御方法 http://msdn.microsoft.com/msdnmag/issues/06/11/SQLSecurity/default.aspx?loc=zh Stop SQL Injection Attacks Before They Stop You http://msdn.microsoft.com/msdnmag/issues/04/09/SQLInjection/ 很不错的文章
别人的经验: 彻底杜绝SQL注入 1.不要使用sa用户连接数据库 2、新建一个public权限数据库用户,并用这个用户访问数据库 3、[角色]去掉角色public对sysobjects与syscolumns对象的select访问权限 4、[用户]用户名称-> 右键-属性-权限-在sysobjects与syscolumns上面打“×” 5、通过以下代码检测(失败表示权限正确,如能显示出来则表明权限太高): DECLARE @T varchar(255), @C varchar(255) DECLARE Table_Cursor CURSOR FOR Select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype= 'u ' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN print @c FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor --------------------------------------------------------------- http://topic.csdn.net/u/20090326/11/5e584897-2dd7-4e10-af1b-9b48b146af8e.html?seed=1427037238
注意参数检测就是了. 有两个原则, 1. 不信任客户提交的任何东西 2. 不信任客户端代码对参数的验证. 客户端代码对参数的验证一定程度上减少了向服务器请求和处理的次数,减轻了服务器压力,减少了不必要的回传,但这仅限于一般用户.真正的参数检测,服务器端必不可少. .net里因为很多变量类型不能隐式转义, 比如一个int型数据,当客户端提交一个string类型值时,程序会报错,就不存在注入问题. 而string类型参数, 要么对传入的string类型数据值中的 '进行转义 '' 比如 C# codestring value=Request["Value"].ToString.Replace("'","''")datetime型数据,需要验证是否date,可以自定义一个isDate函数.具体的可以使用try cache来实现这个isDate函数 推荐的作法是 执行SQL语句时,不要用拼语句的方式,而以存储过程,或以带参数的语句方式执行,这样就不必考滤注入问题了. 当参数中含有'这样的字符时,SQL自己会处理. 比如 DECLARE @s VARCHAR(10) SET @s='aaab'' or ''1''=''1' --这里是直接在SQL里赋值时需要这么转义.在.net里相当于 string s="aaab' or '1'='1"; 然后parameters中某个parm赋值为s. SELECT * FROM tb WHERE f=@s
用参数方式(带参数的语句或存储过程)执行时. 它本身就是字串,何来你的这个值? SQL里不会当 @s= '用户名-- '或者 ' or 1=1-- ' 它会转义的相当于 @s='用户名-- ''或者 '' or 1=1-- ' ',--这些都是字串值,没有问题.
SQL里不会当 @s= '用户名-- '或者 ' or 1=1-- ' 它会转义的相当于 @s= '用户名-- ' '或者 ' ' or 1=1-- ' ------------------------------------------------------- 简单的一句话,就是 当以字串类型参数传入的变量,它本身就是一个字串,你里面出现再多的字符,它还是这个字串的内容. 我说它会转义,意思是相当于你如果在SQL里将这样的字串赋值给变量的话,那么写法是这样. declare @s varchar(10) select @s='abcd''ef' select len(@s) 是7,不是8,中间实际是代表一个',而不是两个''.这很明显了. cs里 string s="用户名--'or' or 1=1--"; parms[0].value=s; SqlHelper.Execute....(...,parms,..);sql里执行 select * from tb where id=@s @s的值就是 string s的值. 若SQL里用""来定界字串的话, 也即@s的值是 @s="用户名--'or' or 1=1--" 但是SQL里是用''来定界字串,也即 @s的值是 @s='用户名--''or'' or 1=1--' 这里跟CS变量s里本身含有"要转义一样. 比如s的值本来就是 abcd"ef 那么你要写做 string s="abcd\"ef"; sql里 @s 的值本来是 abcd'ef 那么转义就定做 @s='abcde''ef' sql里用''来转义',cs里用\"来转义", 一样的道理. 也即 declare @s varchar(10) set @s='abcd''ef' 写是这样写,其实 @s的值还是 abcd'ef所有语言都是一样的. 字串有定界符, 如果字串变量要赋字串值,而字串值中又出现与定界符相同的字符时,这时就需要转义. cs: string s="abcd\"ef"; vb string s="abcd""ef" sql set @s='abcd''ef' js var s="abcd\"ef"; etc. 当然,需要转义的字符不仅限于与定界符相同的字符,这里不一一举了.
新型 SQL 截断攻击和防御方法
http://msdn.microsoft.com/msdnmag/issues/06/11/SQLSecurity/default.aspx?loc=zh
Stop SQL Injection Attacks Before They Stop You
http://msdn.microsoft.com/msdnmag/issues/04/09/SQLInjection/
很不错的文章
彻底杜绝SQL注入 1.不要使用sa用户连接数据库
2、新建一个public权限数据库用户,并用这个用户访问数据库
3、[角色]去掉角色public对sysobjects与syscolumns对象的select访问权限
4、[用户]用户名称-> 右键-属性-权限-在sysobjects与syscolumns上面打“×”
5、通过以下代码检测(失败表示权限正确,如能显示出来则表明权限太高):
DECLARE @T varchar(255),
@C varchar(255)
DECLARE Table_Cursor CURSOR FOR
Select a.name,b.name from sysobjects a,syscolumns b
where a.id=b.id and a.xtype= 'u ' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN print @c
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
---------------------------------------------------------------
http://topic.csdn.net/u/20090326/11/5e584897-2dd7-4e10-af1b-9b48b146af8e.html?seed=1427037238
有两个原则,
1. 不信任客户提交的任何东西
2. 不信任客户端代码对参数的验证. 客户端代码对参数的验证一定程度上减少了向服务器请求和处理的次数,减轻了服务器压力,减少了不必要的回传,但这仅限于一般用户.真正的参数检测,服务器端必不可少.
.net里因为很多变量类型不能隐式转义, 比如一个int型数据,当客户端提交一个string类型值时,程序会报错,就不存在注入问题.
而string类型参数, 要么对传入的string类型数据值中的 '进行转义 ''
比如
C# codestring value=Request["Value"].ToString.Replace("'","''")datetime型数据,需要验证是否date,可以自定义一个isDate函数.具体的可以使用try cache来实现这个isDate函数 推荐的作法是
执行SQL语句时,不要用拼语句的方式,而以存储过程,或以带参数的语句方式执行,这样就不必考滤注入问题了.
当参数中含有'这样的字符时,SQL自己会处理.
比如
DECLARE @s VARCHAR(10)
SET @s='aaab'' or ''1''=''1' --这里是直接在SQL里赋值时需要这么转义.在.net里相当于 string s="aaab' or '1'='1"; 然后parameters中某个parm赋值为s.
SELECT * FROM tb WHERE f=@s
SQL里不会当 @s= '用户名-- '或者 ' or 1=1-- '
它会转义的相当于 @s='用户名-- ''或者 '' or 1=1-- '
',--这些都是字串值,没有问题.
它会转义的相当于 @s= '用户名-- ' '或者 ' ' or 1=1-- '
-------------------------------------------------------
简单的一句话,就是 当以字串类型参数传入的变量,它本身就是一个字串,你里面出现再多的字符,它还是这个字串的内容.
我说它会转义,意思是相当于你如果在SQL里将这样的字串赋值给变量的话,那么写法是这样.
declare @s varchar(10)
select @s='abcd''ef'
select len(@s)
是7,不是8,中间实际是代表一个',而不是两个''.这很明显了.
cs里
string s="用户名--'or' or 1=1--";
parms[0].value=s;
SqlHelper.Execute....(...,parms,..);sql里执行
select * from tb where id=@s
@s的值就是 string s的值.
若SQL里用""来定界字串的话, 也即@s的值是 @s="用户名--'or' or 1=1--"
但是SQL里是用''来定界字串,也即 @s的值是 @s='用户名--''or'' or 1=1--'
这里跟CS变量s里本身含有"要转义一样.
比如s的值本来就是 abcd"ef
那么你要写做
string s="abcd\"ef";
sql里 @s 的值本来是 abcd'ef
那么转义就定做
@s='abcde''ef'
sql里用''来转义',cs里用\"来转义", 一样的道理.
也即
declare @s varchar(10)
set @s='abcd''ef'
写是这样写,其实 @s的值还是 abcd'ef所有语言都是一样的.
字串有定界符, 如果字串变量要赋字串值,而字串值中又出现与定界符相同的字符时,这时就需要转义.
cs:
string s="abcd\"ef";
vb
string s="abcd""ef"
sql
set @s='abcd''ef'
js
var s="abcd\"ef";
etc.
当然,需要转义的字符不仅限于与定界符相同的字符,这里不一一举了.