.Net 全局过滤,防止SQL注入

问题背景:由于公司需要整改的老系统的漏洞检查,而系统就是没有使用参数化SQL即拼接查询语句开发的程序,导致漏洞扫描出现大量SQL注入问题。

解决方法:最好的办法就是不写拼接SQL,改用参数化SQL,推荐新项目使用,老项目改起来比较麻烦,花费的时间也多,最后选择用全局SQL过滤器过滤前端发送的请求内容。

代码:

cs 复制代码
/// <summary>
    /// 防止输入参数sql注入:Post Get Cookies
    /// </summary>
    public class SqlFilter : ActionFilterAttribute
    {
        private const string FilterSql = "execute,exec,select,insert,update,delete,create,drop,alter,exists,table,sysobjects,truncate,union,and,order,xor,or,mid,cast,where,asc,desc,xp_cmdshell,join,declare,nvarchar,varchar,char,sp_oacreate,wscript.shell,xp_regwrite,',%,;,--";

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // -----------------------防 Post 注入-----------------------
            if (filterContext.HttpContext.Request.Form != null)
            {
                var isReadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
                //把 Form 属性改为可读写
                isReadonly?.SetValue(filterContext.HttpContext.Request.Form, false, null);

                for (var k = 0; k < filterContext.HttpContext.Request.Form.Count; k++)
                {
                    var inputKey = filterContext.HttpContext.Request.Form.Keys[k];
                    var inputValue = filterContext.HttpContext.Request.Form[inputKey];
                    var filters = FilterSql.Split(',');
                    inputValue = filters.Aggregate(inputValue, (current, filterSql) => Regex.Replace(current, filterSql, "", RegexOptions.IgnoreCase));
                    filterContext.HttpContext.Request.Form[inputKey] = inputValue;
                }
            }


            // -----------------------防 GET 注入-----------------------
            if (filterContext.HttpContext.Request.QueryString != null)
            {
                var isReadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
                //把 QueryString 属性改为可读写
                isReadonly?.SetValue(filterContext.HttpContext.Request.QueryString, false, null);

                for (var k = 0; k < filterContext.HttpContext.Request.QueryString.Count; k++)
                {
                    var inputKey = filterContext.HttpContext.Request.QueryString.Keys[k];
                    var inputValue = filterContext.HttpContext.Request.QueryString[inputKey];
                    var filters = FilterSql.Split(',');
                    inputValue = filters.Aggregate(inputValue, (current, filterSql) => Regex.Replace(current, filterSql, "", RegexOptions.IgnoreCase));
                    filterContext.HttpContext.Request.QueryString[inputKey] = inputValue;
                }
            }


            // -----------------------防 Cookies 注入-----------------------
            if (filterContext.HttpContext.Request.Cookies.Count > 0)
            {
                var isReadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
                //把 Cookies 属性改为可读写
                isReadonly?.SetValue(filterContext.HttpContext.Request.Cookies, false, null);

                for (var k = 0; k < filterContext.HttpContext.Request.Cookies.Count; k++)
                {
                    var inputKey = filterContext.HttpContext.Request.Cookies.Keys[k];
                    var inputValue = filterContext.HttpContext.Request.Cookies[inputKey]?.Value;
                    var filters = FilterSql.Split(',');
                    inputValue = filters.Aggregate(inputValue, (current, filterSql) => Regex.Replace(current, filterSql, "", RegexOptions.IgnoreCase));
                    if (!(filterContext.HttpContext.Request.Cookies[inputKey] is null))
                    {
                        filterContext.HttpContext.Request.Cookies[inputKey].Value = inputValue;
                    }
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }
相关推荐
l1t12 分钟前
DeepSeek总结的DuckDB使用 WITH RECURSIVE 和 USING KEY 进行聚合的特性
sql·duckdb
菜鸟特工00729 分钟前
javax.net.ssl.SSLPeerUnverifiedException 异常如何处理
网络协议·.net·ssl
l1t34 分钟前
DeepSeek总结的PostgreSQL解码GIF文件SQL移植到DuckDB的性能优化方法
sql·postgresql·性能优化
猫头虎41 分钟前
基于信创openEuler系统安装部署OpenTeleDB开源数据库的实战教程
数据库·redis·sql·mysql·开源·nosql·database
kali-Myon1 小时前
2025春秋杯网络安全联赛冬季赛-day1
java·sql·安全·web安全·ai·php·web
牧马人win2 小时前
Dapper轻量级扩展库SmartDapper
.net·dapper
QT.qtqtqtqtqt3 小时前
SQL注入漏洞
java·服务器·sql·安全
吹牛不交税3 小时前
安装Framework4.0时提示:Microsoft .NET Framework 4 已是此操作系统的一部分。不需要安装 .NET Framework
microsoft·.net
龙山云仓3 小时前
MES系统超融合架构
大数据·数据库·人工智能·sql·机器学习·架构·全文检索
无风听海4 小时前
.NET10之ASP.NET Core的Filter管线
java·asp.net·.net