.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);
        }
    }
相关推荐
陈皮糖..5 小时前
27 届运维实习笔记|第三、四周:从流程熟练到故障排查,企业运维实战深化
运维·笔记·sql·nginx·ci/cd·云计算·jenkins
l1t9 小时前
DeepSeek v4辅助生成的单文件SQL查询示例页面
javascript·数据库·sql
それども10 小时前
Spring Bean 注入的优先级顺序
java·数据库·sql·spring
张子行的博客10 小时前
SQL 调优实战:跨表排序性能提升之路
数据库·sql·oracle
旺王雪饼 www13 小时前
MySQL常用查询语句
数据库·sql
Carsene14 小时前
开篇:我们距离理想的 Java SQL DSL 还有多远?
java·sql
看海的四叔14 小时前
【SQL】SQL的日期与时间函数
数据库·hive·sql·数据分析·时间函数·日期函数
看海的四叔15 小时前
【SQL】SQL-常见窗口函数有哪些-上篇
数据库·hive·sql·mysql·数据分析·窗口函数
wwyyxx2615 小时前
Linux 下 .NET 程序 CPU 异常占用排查记录
linux·.net·调试
bilI LESS15 小时前
SQL多行数据合并到一行中的一个字段
数据库·sql