当前位置:编程学习 > C#/ASP.NET >>

C# 防注入问题 --解决了另加100分

IIS访问记录:
/img/icon.gif - 80 - 114.102.132.148 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729;+aff-kingsoft-ciba;+staticlogin:product=cbpro09&act=login&info=ZmlsZW5hbWU9Y2liYXNldHVwLmV4ZSZtYWM9MkFENjI3NEIxMjhDNDM2NThGRjdDNDkwNzBBMjQzQzMmcGFzc3BvcnQ9JnZlcnNpb249MjAwOS4wNC4yMS4xMC4zMDImY3Jhc2h0eXBlPTE=&verify=b6efa906f08890a83ac8fb3dceec18cf) 


我的sql防注入代码:

        public static bool CheckBadWord(string str)
        {
            string pattern = @"select|insert|delete|from|count\(|drop table|update|truncate|asc\(|mid\(|char\(|xp_cmdshell|exec   master|netlocalgroup administrators|net user|or|and|alter|staticlogin";
            if (Regex.IsMatch(str, pattern, RegexOptions.IgnoreCase))
                return true;
            return false;
        }


        public static string Filter(string str)
        {
            string[] pattern = { "select", "insert", "delete", "from", "count\\(", "drop table", "update", "truncate", "asc\\(", "mid\\(", "char\\(", "xp_cmdshell", "exec   master", "netlocalgroup administrators", "net user", "or", "and", "alter", "staticlogin" };
            for (int i = 0; i < pattern.Length; i++)
            {
                str = str.Replace(pattern[i].ToString(), "");
            }
            return str;
        }


结果系统还有被注入木马,请C#高手指点,多谢了~~~ --------------------编程问答-------------------- 使用存储过程,不直接是用sql语句。 --------------------编程问答-------------------- 检查代码,是否有SQL拼接 参数操作
检查服务器的配置
是否存在JS注入漏洞如编辑器,上传文件等
http://topic.csdn.net/u/20090729/14/26381958-0D6E-4B90-BC90-D275E9621F93.html --------------------编程问答-------------------- 使用参数化操作 --------------------编程问答-------------------- 使用存储过程和带参数的sql语句   --------------------编程问答-------------------- 存储过程 --------------------编程问答-------------------- 我需要具体的解决方案,我多c#属于菜鸟啊,大侠们帮帮忙! --------------------编程问答-------------------- 没想到.net也有通用防注入代码.. --------------------编程问答-------------------- C#完全可以实现防注入:
1、所有输入均先编码再送数据库
   string usernametemp = HttpUtility.HtmlEncode(TextboxUserName.Text.Trim() );
2。所有sql语句或存储过程调用,均采用参数实现。
   SqlParameter[] prams = {  Database.MakeInParam("@uid", SqlDbType.UniqueIdentifier, 16, uid),
                              Database.MakeInParam("@secques", SqlDbType.Char, 10, secques),
                           };
         bool res= Convert.ToInt32(Database.ExecuteScalar(CommandType.Text,
                                                          "SELECT  COUNT(*) FROM users WHERE uid=@uid AND secques=@secques", prams)) > 0;
数据库类可以采用微软的dbhelp类实现。

只要保证了这两条,完全可以防止住sql注入。
--------------------编程问答-------------------- 以上2条必须严格执行,肯定能让你不须为sql注入担心。

  --------------------编程问答--------------------
引用 2 楼 wuyq11 的回复:
检查代码,是否有SQL拼接 参数操作
检查服务器的配置
是否存在JS注入漏洞如编辑器,上传文件等
http://topic.csdn.net/u/20090729/14/26381958-0D6E-4B90-BC90-D275E9621F93.html


好东西,要顶 --------------------编程问答-------------------- 使用存储过程或者LINQ都可以的
--------------------编程问答--------------------   存储过程又不是万能的   如果传入的也是一个带条件的查询语句 不一样也可以在里面做文章吗》 --------------------编程问答-------------------- 学习学习 --------------------编程问答--------------------
引用 8 楼 civilman 的回复:
C#完全可以实现防注入:
1、所有输入均先编码再送数据库
  string usernametemp = HttpUtility.HtmlEncode(TextboxUserName.Text.Trim() );
2。所有sql语句或存储过程调用,均采用参数实现。
  SqlParameter[] prams = { Database.MakeInParam("@uid", SqlDbTy……


tong yi --------------------编程问答--------------------
引用 12 楼 xiaoyuan245437 的回复:
  存储过程又不是万能的   如果传入的也是一个带条件的查询语句 不一样也可以在里面做文章吗》


真要将查询条件字符串当参数传入存储过程,那样的存储过程感觉完全是没必要存在的...
参数化就是最好的防注入方法,存储过程里也可以用sp_executesql来参数化

存储前也应该验证数据的长度,格式等.. --------------------编程问答-------------------- 你不认识、不研究木马,干嘛先自欺欺人地硬说跟什么SQL注入有关系呢?

csdn随便说个时髦词就能信吗?动用自己的大脑来了解前因后果啊! --------------------编程问答-------------------- 这个访问纪录和注入有什么关系? --------------------编程问答-------------------- 就好象10天前我们的一个软件进行测试,测试人员跟开发人员争吵起来,负责人跟我说:“为什么你们不过滤特殊字符”?我说:“如果有什么bug我会跟开发人员说立刻改。在xxxx(bug管理系统)上明确给出bug的测试数据,确实发现了结果的bug,会给用户造成任何损失,我立刻让开发人员改。”于是他立刻回去说服他的人了——因为他立刻明白了。


同样,比如在任何需要录入文本的地方输入引号之类的字符会引起bug,这能证明应该过滤字符?我百分之百地断言,这是扯淡!如果录入引号之类的字符,应该正常地输入到数据库等后台系统中,而不应该引起任何bug,这才是软件开发之道。而只会过滤字符,这种程序员是干什么吃的(基本编程技术呢)? --------------------编程问答-------------------- 把人云亦云的习惯跟实际真实的设计撇开,不要用什么“SQL 注入”作为理由来过滤字符。只有业务确实要过滤某些字符时才应该过滤这些字符。而业务可以随时撤销这些成事不足败事有余的约束(例如我们在许多聊天软件注册时就可以输入火星文、各种特殊符号)。 --------------------编程问答--------------------
引用 17 楼 caozhy 的回复:
这个访问纪录和注入有什么关系?

我也是这么理解的。有些时候根本不用过滤,过滤后会引起用户反感的。 --------------------编程问答--------------------
引用 20 楼 wubudang 的回复:
引用 17 楼 caozhy 的回复:
这个访问纪录和注入有什么关系?

我也是这么理解的。有些时候根本不用过滤,过滤后会引起用户反感的。

日,引用错误。CSDN这点不好,自己的回复都不能修改。 --------------------编程问答-------------------- 就这个问题本身是无厘头的。lz的逻辑是:“我都阉割我自己了,怎么还没有自动变成东方不败”?

其实,你认识金庸或者林青霞吗?或者你认识几个在csdn上说什么过滤字符来“防SQL注入”的人让他来为你的网站的问题埋单去啊。

对于自己进行开发,就是要在功能不减少的情况下做出经得起测试的代码,而不是学着人家阉割自己的代码。 --------------------编程问答-------------------- 关键字过滤。。。

sql语句参数话。

最好前台不让用户看到详细错误,配置好错误页

前台输入设置最大值。。。防止文本溢出。。

都是小小经验。。。我也来看看大牛的经验

--------------------编程问答-------------------- 不用字符串拼接,用参数。 --------------------编程问答-------------------- 用参数。。。。在业务层对字段或参数进行长度等校验。。大部分问题 解决了 --------------------编程问答-------------------- 不用字符串拼接,用参数 --------------------编程问答--------------------
引用 22 楼 sp1234 的回复:
就这个问题本身是无厘头的。lz的逻辑是:“我都阉割我自己了,怎么还没有自动变成东方不败”?

其实,你认识金庸或者林青霞吗?或者你认识几个在csdn上说什么过滤字符来“防SQL注入”的人让他来为你的网站的问题埋单去啊。

对于自己进行开发,就是要在功能不减少的情况下做出经得起测试的代码,而不是学着人家阉割自己的代码。

lz的逻辑是:“我都阉割我自己了,怎么还没有自动变成东方不败”?
sp1234仍旧如此犀利! --------------------编程问答-------------------- 最好是用存储过程。 --------------------编程问答-------------------- 最好是用存储过程。 现在大都喜欢用存储过程
--------------------编程问答-------------------- 路过,看看你们的经验,我是初学者哈 --------------------编程问答-------------------- 初学者····· --------------------编程问答-------------------- 安全是要考虑的,用带参数的sql语句吧 --------------------编程问答-------------------- 1.使用参数
2.对于必须拼接语句的地方,一般都是查询了,对敏感字符串进行转换
3.转换按级别进行,从select到ddl到dml分级 --------------------编程问答--------------------
引用 18 楼 sp1234 的回复:
就好象10天前我们的一个软件进行测试,测试人员跟开发人员争吵起来,负责人跟我说:“为什么你们不过滤特殊字符”?我说:“如果有什么bug我会跟开发人员说立刻改。在xxxx(bug管理系统)上明确给出bug的测试数据,确实发现了结果的bug,会给用户造成任何损失,我立刻让开发人员改。”于是他立刻回去说服他的人了——因为他立刻明白了。


同样,比如在任何需要录入文本的地方输入引号之类的字符会引起……


测试人员对输入的串,正常的测试必须包含带脚本的用例。如上所说,通不过就是BUG。 --------------------编程问答-------------------- 学习了。 --------------------编程问答--------------------    传入参数的时候要过滤一些危险字符 或是特殊符号 --------------------编程问答-------------------- 试试这两种方法: 
第一种: 
squery=lcase(Request.ServerVariables("QUERY_STRING")) 
sURL=lcase(Request.ServerVariables("HTTP_HOST")) 

SQL_injdata =":|;|>|<|--|sp_|xp_|\|dir|cmd|^|(|)|+|$|'|copy|format|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare" 

SQL_inj = split(SQL_Injdata,"|") 

For SQL_Data=0 To Ubound(SQL_inj) 
if instr(squery&sURL,Sql_Inj(Sql_DATA))>0 Then 
Response.Write "SQL通用防注入系统" 
Response.end 
end if 
next 



第二种: 
SQL_injdata =":|;|>|<|--|sp_|xp_|\|dir|cmd|^|(|)|+|$|'|copy|format|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare" 

SQL_inj = split(SQL_Injdata,"|") 

If Request.QueryString<>"" Then 
For Each SQL_Get In Request.QueryString 
For SQL_Data=0 To Ubound(SQL_inj) 
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Then 
Response.Write "SQL通用防注入系统" 
Response.end 
end if 
next 
Next 
End If 

If Request.Form<>"" Then 
For Each Sql_Post In Request.Form 
For SQL_Data=0 To Ubound(SQL_inj) 
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Then 
Response.Write "SQL通用防注入系统" 
Response.end 
end if 
next 
next 
end if 

第三种 
<% 
'--------定义部份------------------ 
Dim Str_Post,Str_Get,Str_In,Str_Inf,Str_Xh,Str_db,Str_dbstr 
'自定义需要过滤的字串,用 "■"分离 
Str_In = "'■;■and■exec■insert■select■delete■update■count■*■%■chr■mid■master■truncate■char■declare" 
'---------------------------------- 
%> 

<% 
Str_Inf = split(Str_In,"■") 
'--------POST部份------------------ 
If Request.Form<>"" Then 
For Each Str_Post In Request.Form 

For Str_Xh=0 To Ubound(Str_Inf) 
If Instr(LCase(Request.Form(Str_Post)),Str_Inf(Str_Xh))<>0 Then 
'--------写入数据库----------头----- 
Str_dbstr="DBQ="+server.mappath("SqlIn.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};" 
Set Str_db=Server.CreateObject("ADODB.CONNECTION") 
Str_db.open Str_dbstr 
Str_db.Execute("insert into SqlIn(Sqlin_IP,SqlIn_Web,SqlIn_FS,SqlIn_CS,SqlIn_SJ) values('"&Request.ServerVariables("REMOTE_ADDR")&"','"&Request.ServerVariables("URL")&"','POST','"&Str_Post&"','"&replace(Request.Form(Str_Post),"'","''")&"')") 
Str_db.close 
Set Str_db = Nothing 
'--------写入数据库----------尾----- 
Response.Write "<Script Language=JavaScript>alert('请不要在参数中包含非法字符尝试注入!');</Script>" 
Response.Write "非法操作!系统做了如下记录:<br>" 
Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>" 
Response.Write "操作时间:"&Now&"<br>" 
Response.Write "操作页面:"&Request.ServerVariables("URL")&"<br>" 
Response.Write "提交方式:POST<br>" 
Response.Write "提交参数:"&Str_Post&"<br>" 
Response.Write "提交数据:"&Request.Form(Str_Post) 
Response.End 
End If 
Next 

Next 
End If 
'---------------------------------- 

'--------GET部份------------------- 
If Request.QueryString<>"" Then 
For Each Str_Get In Request.QueryString 

For Str_Xh=0 To Ubound(Str_Inf) 
If Instr(LCase(Request.QueryString(Str_Get)),Str_Inf(Str_Xh))<>0 Then 
'--------写入数据库----------头----- 
Str_dbstr="DBQ="+server.mappath("SqlIn.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};" 
Set Str_db=Server.CreateObject("ADODB.CONNECTION") 
Str_db.open Str_dbstr 
Str_db.Execute("insert into SqlIn(Sqlin_IP,SqlIn_Web,SqlIn_FS,SqlIn_CS,SqlIn_SJ) values('"&Request.ServerVariables("REMOTE_ADDR")&"','"&Request.ServerVariables("URL")&"','GET','"&Str_Get&"','"&replace(Request.QueryString(Str_Get),"'","''")&"')") 
Str_db.close 
Set Str_db = Nothing 
'--------写入数据库----------尾----- 

Response.Write "<Script Language=JavaScript>alert('请不要在参数中包含非法字符尝试注入!);</Script>" 
Response.Write "非法操作!系统做了如下记录:<br>" 
Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>" 
Response.Write "操作时间:"&Now&"<br>" 
Response.Write "操作页面:"&Request.ServerVariables("URL")&"<br>" 
Response.Write "提交方式:GET<br>" 
Response.Write "提交参数:"&Str_Get&"<br>" 
Response.Write "提交数据:"&Request.QueryString(Str_Get) 
Response.End 
End If 
Next 
Next 
End If 
%> 
第3中方法需要你自己建个数据库表 
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,