不能靠全局拦截关键词防SQL注入,必须以参数化SQL为默认规范;动态语法位置(如ORDER BY、表名)须白名单校验,关键词过滤仅作临时补丁且需解码+日志配合。
不能靠全局拦截关键词来防SQL注入——它既不可靠,又容易误杀正常业务数据。真正该做的,是把参数化SQL作为默认开发规范;拦截器只能当临时补丁,且必须配合解码、白名单、日志等动作才有点用。
直接遍历HttpContext.Request.Form或调用Request.ReadFormAsync()会消耗原始请求流,导致后续Controller收不到数据(尤其JSON Body)。这是.NET Core常见静默失败点。
context.ActionArguments取已绑定的参数值,跳过原始流解析context.HttpContext.Request.QueryString.Value字符串解析;对POST JSON先调context.HttpContext.Request.EnableBuffering(),再重置Position = 0
__RequestVerificationToken、__viewstate(大小写不敏感)——它们含'或--但合法攻击者常用URL编码绕过,比如%27(单引号)、%6f%72(or),不 decode 就等于放行。
WebUtility.UrlDecode() + WebUtility.HtmlDecode()
b(select|union|drop|exec|xp_cmdshell)b加词边界,避免“Select”昵称被误杀--、/*、#,否则admin'--直接逃逸当用户输入出现在SQL语法结构位置(而非值位置)时,字符串过滤完全失效。
ORDER BY <user_input>:不能加引号,参数化也无效 → 必须用白名单校验,如new[] { "name", "created_at" }.Contains(input)
IN (<user_input_list>):多个值拼接 → 用string.Join(",", userInputs.Select(x => $"'{SqlEscape(x)}'))手动转义(仅限极简场景)SELECT * FROM {tableName} → 过滤器无能为力,只能靠严格白名单或拒绝动态构造真正关键的不是写了多少关键词,而是你有没有确认:所有拼接SQL的地方都已迁移到SqlParameter或EF Core的FromSqlRaw(..., params);没迁完的接口,是否单独加了日志+告警+人工复核?漏掉一个string.Format拼接,整个过滤器就形同虚设。