一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

在.NET Core Web API中怎么全局拦截SQL注入关键词?

时间:2026-06-23 09:00:52 编辑:袖梨 来源:一聚教程网

不能靠全局拦截关键词防SQL注入,必须以参数化SQL为默认规范;动态语法位置(如ORDER BY、表名)须白名单校验,关键词过滤仅作临时补丁且需解码+日志配合。

不能靠全局拦截关键词来防SQL注入——它既不可靠,又容易误杀正常业务数据。真正该做的,是把参数化SQL作为默认开发规范;拦截器只能当临时补丁,且必须配合解码、白名单、日志等动作才有点用。

OnActionExecuting里读取参数时别触发多次InputStream

直接遍历HttpContext.Request.Form或调用Request.ReadFormAsync()会消耗原始请求流,导致后续Controller收不到数据(尤其JSON Body)。这是.NET Core常见静默失败点。

  • 优先从context.ActionArguments取已绑定的参数值,跳过原始流解析
  • 若必须读原始Query或Body:对Query用context.HttpContext.Request.QueryString.Value字符串解析;对POST JSON先调context.HttpContext.Request.EnableBuffering(),再重置Position = 0
  • 跳过ASP.NET内置字段:__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拼接,整个过滤器就形同虚设。

热门栏目