首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

(狂散分!2008年SQL防注入第一帖)SQL防注入解决方案大征集,该如何解决

2012-04-05 
(狂散分!!2008年SQL防注入第一帖)SQL防注入解决方案大征集由于公司网站流量巨大,上次被一无名黑客来探了探

(狂散分!!2008年SQL防注入第一帖)SQL防注入解决方案大征集
由于公司网站流量巨大,上次被一无名黑客来探了探路,留下“××到此一游”,虽然没有酿成恶果,但也把Leader吓出一身冷汗。

下面是我昨晚写的的关于URL防SQL注入,先贴为敬。

C# code
        /// <summary>        /// 检测是否含有危险字符(防止Sql注入)        /// </summary>        /// <param name="contents">预检测的内容</param>        /// <returns>返回True或false</returns>        private bool HasDangerousContents(string contents)        {            bool bReturnValue = false;            if (contents.Length > 0)            {                //convert to lower                string sLowerStr = contents.ToLower();                //RegularExpressions                string sRxStr = @"(\sand\s)|(\sand\s)|(\slike\s)|(select\s)|(insert\s)|(delete\s)|(update\s[\s\S].*\sset)|(create\s)|(\stable)|(<[iframe|/iframe|script|/script])|(')|(\sexec)|(\sdeclare)|(\struncate)|(\smaster)|(\sbackup)|(\smid)|(\scount)";                //Match                bool bIsMatch = false;                System.Text.RegularExpressions.Regex sRx = new System.Text.RegularExpressions.Regex(sRxStr);                bIsMatch = sRx.IsMatch(sLowerStr, 0);                if (bIsMatch)                {                    bReturnValue = true;                }            }            return bReturnValue;        }


[解决办法]
不要拼接sql语句直接执行,多使用SqlParameter,SqlCommand
[解决办法]
所有的sql调用全部用存储过程,而且存储过程内部也尽量不要拼接sql语句,这样就能防止injection
[解决办法]
在asp.net中强烈建议通过参数来实现sql而不是sql拼接,因为就算你每一个都过滤百密难有疏 
C# code
SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);             SqlCommand comm=new SqlCommand("update tb1 set vName=@vName,iAge=@iAge where ID=@id",conn);             SqlParameter parm1=new SqlParameter("@vName",SqlDbType.NVarChar,50);             parm1.Value=((TextBox)e.Item.FindControl("name")).Text;             SqlParameter parm2=new SqlParameter("@iAge",SqlDbType.Int);             parm2.Value=((TextBox)e.Item.FindControl("age")).Text;             SqlParameter parm3=new SqlParameter("@id",SqlDbType.Int);             parm3.Value=this.DataGrid1.DataKeys[e.Item.ItemIndex];             comm.Parameters.Add(parm1);             comm.Parameters.Add(parm2);             comm.Parameters.Add(parm3);             conn.Open();             comm.ExecuteNonQuery();             conn.Close();
[解决办法]
存储过程,要不你就得做字符串过滤,也可以用转换,webservice等!要看个人的经验了!比如xwny.aspx?id=2这样的常被注入的例子你可以在你的方法中mode(int64 id)这样定义不就没事了!
[解决办法]
SqlHelper + 参数化存储过程 + 正则表达式
[解决办法]
这个问题应该转到 SQL 时去, 建议使用SP. 这一点我也很赞同.

但T-SQL 有时间比SP要方便一点, 写好过滤 T-SQL 的方法后,还要做
到以下几点 (人个认为)

1、把所有 TextBox (Input type="text" ) 等输入信息的地方,限制一个最大输入长度。
这样至少可以给输入危险字符带来限制,这还是有点作用的,况且这样做并不难。(JavaScript遍历)

2、楼主也提到过,URL可能也会传输入危险字符。这个解决,你可以用URL重写功能,这样比较好,至少可以增加难度
例如:abc.aspx?year=2008&month=5 可重写为 abc/2008/5 (扩展名是可以隐藏的)

3、把你写的过滤方法及一些防范措施,最好用到 Global 或 http请求 里. (建议Global)

这样应该比较不错。
还有,我想随便问一下楼主,你确认无名的黑客就是SQL注入攻击您的网站的?
或者说你的服务器,本身就是他的一个肉机或别的什么?
[解决办法]
只要先在查询分析器里建好存储过程,我建议最好用视图至于里代码里吗,你多用适配器+SQL参数结合来使用,如有可能再建一个数据封装类来给数据传输加密.
其实防注入还是很简单的!


[解决办法]
在解决SQL Injection的可行方案中,基于正则表达式的方案不予考虑,理由有:
1、即使使用了RegexOptions.Compile选项,正则表达式的性能也不很理想,尤其是在楼主“流量巨大”的网站中很可能会造成性能瓶颈。
2、过滤的范围很难把握,不是过宽就是过窄。对楼主的这个例子来说,我的文章中有一个" and "都会被判断为危险字符串;另一方面,这个表达式对"exec"开头的字符串却无能为力。当然如果楼主的这个表达式可以只是针对某一个或几个参数进行验证,这样却必须保证对所有其他的输入参数都写对应的表达式来过滤。

可以使用的方案主要有:
1、使用SqlParameter类
2、在数据库上增加一个抽象层次,防止直接对数据库的操作
3、在数据库方面,应用程序使用专门的帐户,设置其对应的权限,一定不要用管理员
4、避免拼接字符串
[解决办法]
楼主,难道防止SQL注入还要100种不同的方法吗?大家的回答足够了。
1、用SQL参数(参数在Command Text或者存储过程都可以用),不要用加串方式执行
2、合理设置数据库权限,严禁使用sa账号执行商务逻辑,应用程序所使用的数据库帐号权限应当最小化(程序不需要用到的权限一律不给,用不到的表不给访问权,只需要读数据的表不给写权限,等等),这样可以做到及时不幸被SQL注入,亦可以尽量减少损失
[解决办法]
1. 只要不把 参数 拼到语句里就行了

2. 只要把关键字(如单引号,分号等)屏蔽掉就行了

3. 都参数对象就行了
[解决办法]
如果实在没有法要用到拼接,就用SP_EXECUTESQL 系统存储过程防止SQL注入
例如:

SQL code
declare @userid int set @userid = 1 declare @sqlStr nvarchar(1000),@param nvarchar(400) set @sqlStr='select * from table where [userid]=@tuserid' //这里可以拼接字符串,我这里简单点哈 set @param='@tuserid int' execute sp_executesql @sqlstr,@param,@tuserid=@userid     //变量替换
[解决办法]
我是使用404错误结合模板来生成静态的页面,而且程序和生成的静态页面是放在两台不同的服务器的,对外网只开发生成页面,内网放置程序,后台单独另外的服务器,数据库一台服务器。这样一旦新闻有更新的话,自动分布式生成页面,用户和数据库没有交往,这个是解决SQL注入的最好方法。同时还可以生成静态,加快访问速度。
[解决办法]
用正则提取出仅需要的参数,再用SQL参数来提交,安全性还是非常高的

热点排行