适用于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命令.具 ...
随机推荐
- TopicsExtraction with NMF & LDA
""" ================================================================================= ...
- 《代码不朽:编写可维护软件的10大要则(C#版)》读后感
本书作者Joost Visser,译者张若飞.本书讲解了编写可维护代码的10个要则,从目录就可以看出这10点分别是: 编写短小的代码单元(15行以内,在大部分情况下还是能实现的,但是当我们使用Linq ...
- 【转】RPC介绍
转自:http://www.cnblogs.com/Vincentlu/p/4185299.html 摘要: RPC——Remote Procedure Call Protocol,这是广义上的解释, ...
- 【原创】岁月如歌 一款网易歌单生成pdf的软件
介绍 这是一款可以将网易云音乐的歌单中所有歌词输出为pdf的软件. 项目持续维护地址 http://brightguo.com/song-list-to-pdf/ 目前没有搜到相关网易歌单导出为pdf ...
- Kotlin基础语法学习
Kotline简介 Kotlin是一门与Swift类似的静态类型JVM语言,由JetBrains设计开发并开源.与Java相比,Kotlin的语法更简洁.更具表达性,而且提供了更多的特性,比如,高阶函 ...
- 微信支付接口调用H5(C#)
H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付.主要用于触屏版的手机浏览器请求微信支付的场景.可以方便的从外部浏览器唤 ...
- 背水一战 Windows 10 (107) - 通知(Toast): 提示音, 特定场景
[源码下载] 背水一战 Windows 10 (107) - 通知(Toast): 提示音, 特定场景 作者:webabcd 介绍背水一战 Windows 10 之 通知(Toast) 提示音 特定场 ...
- 第四节:详细讲解Java中的类和面向对象思想
前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...
- SpringMVC框架一:搭建测试
这里做一个Demo:展示商品列表 新建Dynamic Web Project: 导入jar包,放在lib下: 放入Lib文件夹之后,会自动build path 接下来配置web.xml: <?x ...
- MySQL 非空约束位置不同对自增列造成的影响
MySQL版本 select version(); +------------+ | version() | +------------+ | 5.7.21-log | +------------+ ...