适用于WebApi的SQL注入过滤器
开发工具:Visual Studio 2017
C#版本:C#7.1
最有效的防止SQL注入的方式是调用数据库时使用参数化查询。
但是如果是接手一个旧的WebApi项目,不想改繁多的数据库访问层的代码,应该如何做。
我的解决方案是加一个过滤器。
先写过滤方法,上代码
using System;
using System.Collections.Generic;
using System.Web;
namespace Test
{
/// <summary>
/// 防止SQL注入
/// </summary>
public class AntiSqlInject
{
public static AntiSqlInject Instance = new AntiSqlInject();
/// <summary>
/// 初始化过滤方法
/// </summary>
static AntiSqlInject()
{
SqlKeywordsArray.AddRange(SqlSeparatKeywords.Split('|'));
SqlKeywordsArray.AddRange(Array.ConvertAll(SqlCommandKeywords.Split('|'), h => h + " "));
SqlKeywordsArray.AddRange(Array.ConvertAll(SqlCommandKeywords.Split('|'), h => " " + h));
}
private const string SqlCommandKeywords = "and|exec|execute|insert|select|delete|update|count|chr|mid|master|" +
"char|declare|sitename|net user|xp_cmdshell|or|create|drop|table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|orderhaving|having|by|count|*|truncate|like";
private const string SqlSeparatKeywords = "'|;|--|\'|\"|/*|%|#";
private static readonly List<string> SqlKeywordsArray = new List<string>();
/// <summary>
/// 是否安全
/// </summary>
/// <param name="input">输入</param>
/// <returns>返回</returns>
public bool IsSafetySql(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return true;
}
input = HttpUtility.UrlDecode(input).ToLower();
foreach (var sqlKeyword in SqlKeywordsArray)
{
if (input.IndexOf(sqlKeyword, StringComparison.Ordinal) >= 0)
{
return false;
}
}
return true;
}
/// <summary>
/// 返回安全字符串
/// </summary>
/// <param name="input">输入</param>
/// <returns>返回</returns>
public string GetSafetySql(string input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
if (IsSafetySql(input)) { return input; }
input = HttpUtility.UrlDecode(input).ToLower();
foreach (var sqlKeyword in SqlKeywordsArray)
{
if (input.IndexOf(sqlKeyword, StringComparison.Ordinal) >= 0)
{
input = input.Replace(sqlKeyword, string.Empty);
}
}
return input;
}
}
}
然后是过滤器,先上代码
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Test
{
/// <inheritdoc>
/// <cref></cref>
/// </inheritdoc>
/// <summary>
/// SQL注入过滤器
/// </summary>
public class AntiSqlInjectFilter : ActionFilterAttribute
{
/// <inheritdoc />
/// <summary>
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(HttpActionContext filterContext)
{
base.OnActionExecuting(filterContext);
var actionParameters = filterContext.ActionDescriptor.GetParameters();
var actionArguments = filterContext.ActionArguments;
foreach (var p in actionParameters)
{
var value = filterContext.ActionArguments[p.ParameterName];
var pType = p.ParameterType;
if (value == null)
{
continue;
}
//如果不是值类型或接口,不需要过滤
if (!pType.IsClass) continue;
if (value is string)
{
//对string类型过滤
filterContext.ActionArguments[p.ParameterName] = AntiSqlInject.Instance.GetSafetySql(value.ToString());
}
else
{
//是一个class,对class的属性中,string类型的属性进行过滤
var properties = pType.GetProperties();
foreach (var pp in properties)
{
var temp = pp.GetValue(value);
if (temp == null)
{
continue;
}
pp.SetValue(value, temp is string ? AntiSqlInject.Instance.GetSafetySql(temp.ToString()) : temp);
}
}
}
}
}
}
思路是,加过滤器继承ActionFilterAttribute,重写OnActionExecuting方法,获取入参,对入参中的string类型的所有数据进行过滤。两种情况,一是参数是string类型,二是类的属性。过滤器搞定。
过滤器有两种使用方式,一种是在具体的方法上添加
[HttpPut,Route("api/editSomething")]
[AntiSqlInjectFilter]
public async Task<bool> EditSomeThingAsync([FromBody]SomeThingmodel)
{
var response = await SomeThingBusiness.Editsync(model);
return response;
}
一种是全局配置,在WebApiConfig.cs文件中的Register方法中加上过滤器
using System.Web.Http;
namespace Test
{
/// <summary>
/// WebApi配置
/// </summary>
public static class WebApiConfig
{
/// <summary>
/// 注册配置服务
/// </summary>
/// <param name="config"></param>
public static void Register(HttpConfiguration config)
{
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//全局配置防止SQL注入过滤
config.Filters.Add(new AntiSqlInjectFilter());
}
}
}
测试有效。
适用于WebApi的SQL注入过滤器的更多相关文章
- 结合jquery的前后端加密解密 适用于WebApi的SQL注入过滤器 Web.config中customErrors异常信息配置 ife2018 零基础学院 day 4 ife2018 零基础学院 day 3 ife 零基础学院 day 2 ife 零基础学院 day 1 - 我为什么想学前端
在一个正常的项目中,登录注册的密码是密文传输到后台服务端的,也就是说,首先前端js对密码做处理,随后再传递到服务端,服务端解密再加密传出到数据库里面.Dotnet已经提供了RSA算法的加解密类库,我们 ...
- Java 防SQL注入过滤器(拦截器)代码
原文出自:https://blog.csdn.net/seesun2012 前言 浅谈SQL注入: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符 ...
- SQL盲注、SQL注入 - SpringBoot配置SQL注入过滤器
1. SQL盲注.SQL注入 风险:可能会查看.修改或删除数据库条目和表. 原因:未对用户输入正确执行危险字符清理. 固定值:查看危险字符注入的可能解决方案. 2. pom.xml添加依赖 ...
- SQL注入的优化和绕过
作者:Arizona 原文来自:https://bbs.ichunqiu.com/thread-43169-1-1.html 0×00 ~ 介绍 SQL注入毫无疑问是最危险的Web漏洞之一,因为我们将 ...
- 170605、防止sql注入(二)
java filter防止sql注入攻击 原理,过滤所有请求中含有非法的字符,例如:, & < select delete 等关键字,黑客可以利用这些字符进行注入攻击,原理是后台实现使 ...
- Java防止SQL注入2(通过filter过滤器功能进行拦截)
首先说明一点,这个过滤器拦截其实是不靠谱的,比如说我的一篇文章是介绍sql注入的,或者评论的内容是有关sql的,那会过滤掉:且如果每个页面都经过这个过滤器,那么效率也是非常低的. 如果是要SQL注入拦 ...
- 使用过滤器解决SQL注入和跨站点脚本编制
1 SQL注入.盲注 1.1 SQL注入.盲注概述 Web 应用程序通常在后端使用数据库,以与企业数据仓库交互.查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本).Web 应用 ...
- XSS过滤JAVA过滤器filter 防止常见SQL注入
Java项目中XSS过滤器的使用方法. 简单介绍: XSS : 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩 ...
- JSP使用过滤器防止SQL注入
什么是SQL注入攻击?引用百度百科的解释: sql注入_百度百科: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具 ...
随机推荐
- influence maximization 第二弹
Robust Influence Maximization 首先简要介绍一下这个问题:在一个社交网络图中寻找固定数量的节点,使得这些节点对所有节点的影响值尽可能的大.先对这个问题给出形式化的定义:给一 ...
- N!中末尾有多少个0
问题:先从100!的末尾有多少零 => 再推广到 任意N!的末尾有多少个零 分析:首先想到慢慢求解出100!或N!,但计算机表示数有限,且要防止溢出. 则从数学上分析:一 ...
- Appium之xpath定位元素
原文:http://www.cnblogs.com/cnkemi/p/9180525.html appium也是以webdriver为基的,对于元素的定位也基本一致,只是增加一些更适合移动平台的独特方 ...
- java.exe
进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 线程(例:FlashGet):就是进程中一个独立的控制单元.线程在控制着进程的执行.一个进程中 ...
- datepart in ssis
"\\\\"+_"+ (DT_STR,4,1252)DATEPART( "yyyy" , @[System::StartTime] ) + RIGHT ...
- 14.不同条目的listview
分类界面 整个项目的逻辑就是这样的 CategoryInfo public class CategoryInfo { private String title; private String url ...
- npm安装webpack失败(mac和window都可能会遇到这样的情况,以下问题主要以mac为例)
问题描述:我想查看一下webpack的版本,于是输入了命令webpack -v, 结果如下图所示: 注:这里提示我们要安装webpack-cli,是因为到了webpack4, webpack 已经将 ...
- Oracle创建表空间、用户管理、角色管理
内容:Oracle创建表空间.用户管理.角色管理 1.用系统用户登录Oracle 默认的系统用户: sys/system.sysman.scott sys:权限最大,超级用户,可以完成所有任务, 默认 ...
- java常见面试题及部分答案
1.Redis常见的存储数据类型 list(列表类型) set(集合类型) zset(有序集合类型) string(字符串类型) hash(散装类型) 2.log4j的级别 debug:日志的最低级别 ...
- Go语言下的线程模型
阅读Go并发编程对go语言线程模型的笔记,解释的非常到,好记性不如烂笔头,忘记的时候回来翻一番,在此做下笔记. Go语言的线程实现模型,又3个必知的核心元素,他们支撑起了这个线程实现模型的主要框架: ...