视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
T-SQL篇如何防止SQL注入的解决方法
2020-11-09 07:08:31 责编:小采
文档


1.什么是SQL注入
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。

2.怎么进行SQL注入
关于怎么进行SQL注入,网上已经有很多文章详细介绍过了,可以参考博友滴答的雨的博文 《SQL注入攻防入门详解》,亲测有效。当执行完文中的5、6、7三步的时候,你会发现服务器上的安全保护措施都已是浮云,服务器也因此变成了名副其实的“肉机”。下面附上一张我在本机执行完文中描述的脚本后的效果截图(Win8 x 操作系统):

image
微软的“不禁止即允许(Not forbidden is allow)”的做法使得操作系统像是服务器所穿的镂空礼物一样,美观但却有很多“漏洞”。好了,现在此小黑已经拥有了服务器的管理员权限,很显然元芳怎么看已经不重要了。

3.如何防止SQL注入的发生
滴答的雨已经在博文详细阐述了SQL Server数据库如何进行防注入的操作,这里不再赘述。这一篇我主要说一下对于一个使用拼接SQL进行查询操作的Web应用,怎么进行防注入操作。
先说一些前提,为什么我们要使用拼接SQL的方式进行查询?偷懒呗。这在开发过程中,看似省去了编写参数化部分的代码量,节省了时间和精力。但这样做的结果就是应用的安全性大打折扣,而且拼SQL方式创建的应用,后期的维护难度也很大。SQL参数化查询是最简单有效的避免SQL注入的解决方案,目前主流的ORM框架(MyBatis.NET/NHibernate/EntityFramework)都内置支持并且推荐使用这种方式进行持久层封装。

然而有数据库不支持参数化查询怎么办?是的,你没有看错,确实有这样的数据库存在。吐个槽先,个人认为,一切不支持参数化查询的数据库都是在“耍流氓”,这种天然的缺陷会让小黑们肆无忌惮地去“非礼”服务器,至少是数据库本身。在这样的情况下,我觉得其他功能做得再好也只能算是花拳绣腿,连最基本的数据都保护不了,那不等同于将劳动成果拱手让人。按照存在即合理的逻辑,我们暂且认为它是合理的。

来说说我目前的做法,基于上述数据库创建的Web应用,拼接SQL操作已经渗透到站点的每个页面、每个用户控件,所以我采用的方式是请求过滤。
下面是防SQL注入的操作类:

 1: /// <summary>
 2: ///SqlInject 的摘要说明
 3: /// </summary>
 4: public class SqlInject : System.Web.UI.Page
 5: {
 6: //检测到注入后的处理方式: 0:仅警告;1:警告+记录;2:警告+自定义错误页面;3:警告+记录+自定义错误页面
 7: private const int _type = 0;
 8: private const string errRedirectPage = "/err.aspx";
 9:  
 10: //如果记录注入信息,那么请设置:errMDBpath:数据库路径
 11: private const string errMDBpath = "/SqlInject.mdb";
 12:  
 13:  
 14: //过滤特征字符
 15: //过滤特征字符
 16: private static string StrKeyWord = ConfigurationManager.AppSettings["SqlKeyWord"]; //@"select|insert|delete|from|count(|drop table|update|truncate|asc(|mid(|char(|xp_cmdshell|exec|master|net local group administrators|net user|or|and";
 17: private static string StrRegex = ConfigurationManager.AppSettings["SqlRegex"]; //@";|/|(|)|[|]|{|}|%|@|*|'|!"; // 原始过滤条件:【-|;|,|/|(|)|[|]|{|}|%|@|*|'|!】
 18:  
 19: private HttpRequest request;
 20: public SqlInject(System.Web.HttpRequest _request)
 21: {
 22: this.request = _request;
 23: }
 24: ///<summary>
 25: ///检测SQL注入及记录、显示出错信息
 26: ///</summary>
 27: public void CheckSqlInject()
 28: {
 29: bool isInject = false;
 30: if (CheckRequestQuery() || CheckRequestForm())
 31: {
 32: isInject = true;
 33: }
 34: else
 35: {
 36: return;
 37: }
 38:  
 39: switch (_type)
 40: {
 41: case 0:
 42: ShowErr();
 43: break;
 44: case 1:
 45: ShowErr();
 46: SaveToMdb();
 47: break;
 48: case 2:
 49: ShowErr();
 50: string temp;
 51: System.Web.HttpContext.Current.Response.Write("<script>setTimeout(\"" + "location.href='" + errRedirectPage + "'" + "\",5000)</script>");
 52: break;
 53: case 3:
 54: ShowErr();
 55: SaveToMdb();
 56: System.Web.HttpContext.Current.Response.Write("<script>setTimeout(\"" + "location.href='" + errRedirectPage + "'" + "\",5000)</script>");
 57: break;
 58: default:
 59: break;
 60: }
 61: System.Web.HttpContext.Current.Response.End();
 62:  
 63: }
 : private void SaveToMdb()
 65: {
 66: OleDbConnection conn = new OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + Server.MapPath(errMDBpath));
 67: conn.Open();
 68: OleDbCommand cmd = conn.CreateCommand();
 69:  
 70: cmd.CommandText = "insert into [Record] (sIP,sDate,sPath) values ('" +
 71: request.ServerVariables["REMOTE_ADDR"].ToString() + "','" +
 72: DateTime.Now + "','" + request.ServerVariables["URL"].ToLower() + RelaceSingleQuotes(request.QueryString.ToString()) + "')";
 73: int code = cmd.ExecuteNonQuery();
 74: if (code == 1)
 75: System.Web.HttpContext.Current.Response.Write("<br>****以上信息已记录至日志数据库****");
 76: else
 77: System.Web.HttpContext.Current.Response.Write("<br>日志数据库出错");
 78: conn.Close();
 79:  
 80: }
 81: private string RelaceSingleQuotes(string _url)
 82: {
 83: string URL = _url.Replace("'", "单引号");
 84: return URL;
 85: }
 86: private void ShowErr()
 87: {
 88: //string msg = @"<font color=red>请不要尝试未授权之入侵检测!</font>" + @"<br><br>";
 : //msg += @"操作IP:" + request.ServerVariables["REMOTE_ADDR"] + @"<br>";
 90: //msg += @"操作时间:" + DateTime.Now + @"<br>";
 91: //msg += @"页面:" + request.ServerVariables["URL"].ToLower() + request.QueryString.ToString() + @"<br>";
 92: //msg += @"<a href='#' onclick='javascript:window.close()'>关闭</a>";
 93: //System.Web.HttpContext.Current.Response.Clear();
 94: //System.Web.HttpContext.Current.Response.Write(msg);
 95: System.Web.HttpContext.Current.Response.Write("<script>alert('请不要尝试未授权之入侵检测!');javascript:history.go(-1);</script>");
 96: }
 97: ///<summary>
 98: /// 特征字符
 99: ///</summary>
 100: public static string KeyWord
 101: {
 102: get
 103: {
 104: return StrKeyWord;
 105: }
 106: }
 107: ///<summary>
 108: /// 特征符号
 109: ///</summary>
 110: public static string RegexString
 111: {
 112: get
 113: {
 114: return StrRegex;
 115: }
 116: }
下载本文

显示全文
专题