适用于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命令.具 ...
随机推荐
- 网络操作系统 第十章 DNS服务器管理与配置
1.什么是域名系统?描述域名解析的过程. 1)域名系统:Domain Name System缩写DNS,是因特网的一项核心服务 域名系统作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方 ...
- spring profile
配置,激活profile. 处理测试环境,开发环境,生成环境的不同配置. Javaeconfig配置Profile @Profile注解指定某个bean属于哪一个profile xml配置Profil ...
- Java基础巩固——异常
基础回顾 什么是异常? 在Java程序运行时,常常会出现一些非正常的现象,这种情况称为运行错误.根据其性质可以分为错误和异常. Java程序中所有抛出的异常都必须从Throwable派生而来.类Thr ...
- 大叔学ML第五:逻辑回归
目录 基本形式 代价函数 用梯度下降法求\(\vec\theta\) 扩展 基本形式 逻辑回归是最常用的分类模型,在线性回归基础之上扩展而来,是一种广义线性回归.下面举例说明什么是逻辑回归:假设我们有 ...
- python爬虫学习之使用XPath解析开奖网站
实例需求:运用python语言爬取http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html这个开奖网站所有的信息,并且保存为txt文件. 实例环境:pyth ...
- Visual Studio 开发(二):VS 2017配置FFmpeg开发环境
在上篇文章Visual Studio 开发(一):安装配置Visual Studio Code 中,我们讲了一下如何配置VS CODE,来编写和调试C的代码.如果你已经使用VS Code回顾和复习好C ...
- 音视频编解码——LAME
一.LAME简介 LAME是目前非常优秀的一种MP3编码引擎,在业界,转码成Mp3格式的音频文件时,最常用的就是LAME库.当达到320Kbit/s时,LAME编码出来的音频质量几乎可以和CD的音质相 ...
- Spring理解IOC,DI,AOP作用,概念,理解。
IOC控制反转:创建实例对象的控制权从代码转换到Spring容器.实际就是在xml中配置.配置对象 实例化对象时,进行强转为自定义类型.默认返回类型是Object强类型. ApplicationCon ...
- 什么 是JavaScript中的变量? 部分2
变量:是计算机存储数据的标识符 js中存储数据的方式 都是使用变量 js 中声明变量的方式都是var 存储数据,应该有对应的数据类型js中的字符串类型都用成对的单引号或者双引号包裹起来 变量 1. 变 ...
- ionic2 基于ngx-translate实现多语言切换,翻译
介绍 ngx-translate 是Angular 2+的国际化(i18n)库,在github的地址是箭头 https://github.com/ngx-translate/core 将ngx-tra ...