.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);
        }
    }
相关推荐
爱可生开源社区3 小时前
🧪 你的大模型实验室开张啦!亲手测出最懂你 SQL 的 AI
数据库·sql·llm
用户298698530145 小时前
C#:三行代码,给 Word 文档的文本框“一键清空”
后端·c#·.net
唐青枫11 小时前
C#.NET Expression Tree 深入解析:表达式树、动态查询与运行时代码生成
c#·.net
曲幽19 小时前
FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
python·sql·postgresql·fastapi·web·postgres·db·asyncpg
唐青枫1 天前
C#.NET SignalR 深入解析:实时通信、Hub 与连接管理实战
c#·.net
hez20102 天前
Satori GC:同时做到高吞吐、低延时和低内存占用
c#·.net·.net core·gc·clr
用户8307196840822 天前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
牧马人win2 天前
.NET 开发 MCP 服务器完全指南:打造智能数据库查询助手
ai·.net·mcp
唐青枫2 天前
C#.NET Channel 深入解析:高性能异步生产者消费者模型实战
c#·.net