.Net中的RealProxy实现AOP
序言
这个AOP要从我们公司的一个事故说起,前段时间公司的系统突然在乌云中出现,数据被泄露的一览无余,乌云上显示是SQL注入攻击。呵,多么贴近生活的一个露洞,可谓是人尽皆知啊。然而却华丽丽的给拉我们一记耳光。
那么问题既然来啦,我们.net组有40-50个项目之多吧,怎么去一一补救这一过失呢?什么又是SQL注入呢?再有就是常见的Web漏洞有哪些呢?我们怎么更好的监控我们的系统呢?
那么大家不要嫌我啰嗦,本篇我将对常见的网站攻击与防御,与.Net中AOP实现横切关注点做一些介绍与演示。
常见的web攻击与防御
据数据统计:全球70%的web应用攻击都是来自XSS攻击和SQL注入攻击。此外还有常见的跨站攻击CSRF,Session劫持,文件上传等手段。
XSS攻击
XSS攻击即跨站点脚本攻击(Cross Site Script),看下全称缩写,本应该是CSS无奈,已被样式表占用,只能用个更牛逼的XXX代替,XSS,哈哈,蛋扯完啦,说下什么是XSS,他是攻击者在网页中嵌入恶意程序脚本,当用户打开网页时,脚本程序便开始执行,窃取客户端cookie,用户名,密码,下载执行病毒木马程序等等,牛逼的一塌糊涂,好像你的网站系统成啦他自己的一样。
那么怎么注入的呢?举个例子啊,假如发表个说说,或者微博,发表的内容是 "/><script>alert('123');</script><!- ,那么在某种情况下你可能会让他加载到你的 <input type="text" value="" />中,你再看下你的代码成什么样子啦,就会运行alert();我这里仅仅是一个alert();黑客,就黑的不着边际的黑你啊。
XSS防范:
1、将用户输入的特殊符号如:<,>,'',""转义为<,>,&,"等。
2、对Cookie添加HttpOnly属性,他不能对抗XSS攻击,但可以防止窃取cookie。
CSRF攻击
CSRF攻击即跨站请求攻击(cross site request forgery)。攻击者通过跨站请求,以合法用户的身份进行非法操作,如转账,发表评语等。具体流程如下:
举例说明:假设你在中国银行网站进行转账业务,首先你登陆啦中国银行,进行啦转账,这是假设你的转账连接为http:www.zhongguoyinhang/zz/1000.那么你转完帐后并没有关闭页面。而是访问啦另外一个网站,另外一个网站的一个图片或者连接为攻击者布好的连接:http:www.zhongguoyinhang/zz/1000 。那么很不幸,你又一次进行啦转账。
当然,中国银行会有各种举措。不过这确实是攻击者的一种手段。
CSRF防范:
1、对Cookie添加HttpOnly属性。
2、增加token验证,验证码验证,表单token等。
3、通过Referer识别,来源网站。
SQL注入攻击
SQL注入相信每个开发者都耳熟能详啦。不多说,就是通过sql拼接,让你的sql执行别人想要执行的语句。甚至可恶的update,delete,等等等等!!
SQL注入防范:1、使用orm框架。2、使用预编译语句。3、避免明文存放密码。4、处理好响应的异常,因为异常中会包含关于服务器版本,数据库版本,编程语言甚至数据库连接地址,用户名密码等信息。
文件上传漏洞
文件上传也好理解:就是攻击者上传啦恶意可执行文件或者脚本,并通过脚本获取服务器响应的权利,多可怕,如果他上传个格式化你服务器硬盘的程序,可想而知。怕不怕!!
防范:1、验证后缀名。2、验证魔数。魔数:很多类型的文件,其实的几个字节内容是固定,因此根据这几个字节就能确认文件的类型。这几个字节也称为魔数。3、部署独立的文件服务器。
其实攻击手段还有很多,DDOS,CC,DNS域名劫持,cdn回源攻击等等,大家可以在网上搜搜查查,了解一下。
AOP解决40-50个项目中的sql注入漏洞
这里的aop其实是.Net中的透明代理与真是代理的实现。他让一般开发者不用关心某个横切点,比如接口性能的的记录,日志记录,过滤危险字符,事物提交回滚等等。
首先我们的项目有的用的orm框架,有的没有用,有的用的参数化拼接,有的直接字符串拼接。那么我们这么多项目怎么一下子进行清理盘查呢。我们想拉个办法就是我们的项目都有业务逻辑层去连接数据读写层的。那么我们只要把业务逻辑层这一层的方法参数给过滤一下危险字符,不就可以拉。那么工程开始啦。
namespace A.Helper.Client.Action
{
public class SqlVerifyProxy :RealProxy
{
MarshalByRefObject _target = null;
public SqlVerifyProxy(Type type, MarshalByRefObject target)
: base(type)
{
this._target = target;
}
//覆写Invoke,处理RealProxy截获的各种消息,
//此种方式最简捷,但不能截获远程对象的激活,好在我们并不是真的要Remoting
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage call = (IMethodCallMessage)msg;
IConstructionCallMessage ctr = call as IConstructionCallMessage;
IMethodReturnMessage back = null;
//构造函数,只有ContextBoundObject(Inherit from MarshalByRefObject)对象才能截获构造函数
if (ctr != null)
{
RealProxy defaultProxy = RemotingServices.GetRealProxy(_target);
//如果不做下面这一步,_target还是一个没有直正实例化被代理对象的透明代理,
//这样的话,会导致没有直正构建对象。
defaultProxy.InitializeServerObject(ctr);
//本类是一个RealProxy,它可通过GetTransparentProxy函数得到透明代理
back = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctr, (MarshalByRefObject)GetTransparentProxy());
}
//MarshalByRefObject对象就可截获普通的调用消息,
//MarshalByRefObject对象告诉编译器,不能将其内部简单的成员函数优化成内联代码,
//这样才能保证函数调用都能截获。
else
{
IDictionary<string, object> dic = new Dictionary<string, object>();
dic = actionContext.ActionArguments;
if (dic != null && dic.Count > )
{
foreach (var m in dic)
{
string o = m.Value.ToJson();
Utils.Filter(o);
}
}
back = RemotingServices.ExecuteMessage(_target, call);
}
return back;
}
}
}
namespace A.Helper.Client.Action
{
//从ProxyAttribute继承,自动实现RealProxy植入
[AttributeUsage(AttributeTargets.Class)]
class SqlVerifyProxyAttribute : ProxyAttribute
{
//覆写CreateInstance函数,返回我们自建的代理
public override MarshalByRefObject CreateInstance(Type serverType)
{
MarshalByRefObject obj = base.CreateInstance(serverType);
SqlVerifyProxy proxy = new SqlVerifyProxy(serverType, obj);
return (MarshalByRefObject)proxy.GetTransparentProxy();
}
}
}
好啦,就这么简单,只要业务逻辑层的基类,集成ContextBoundObject添加我们的[SqlVerifyProxy]属性就好啦,这个作为一个dll给其他项目引入,别人不用一个一个再写一遍。不过这也是我们的权宜之计,相信我们以后的项目会有更好的架构设计,来防范诸如此类低级问题的发生。
RealProxy实现AOP业务层事务入侵
让你的代码不用每次都声明事物,你也不必担心你的事物是否提交,或者回滚啦吗?我做了一个示例仅供参考。
/// <summary>
/// 插入可以成功
/// </summary>
public Int32 UpdateTrue(string appName)
{
try
{
using (var conn = GetInstance())
{
string sql = "update aoptran set appName='"+appName+"' where id <10 ";
var result = conn.ExecuteScalar(sql);
return result != null ? Convert.ToInt32(result) : ;
}
}
catch (Exception ex)
{
return ;
}
}
/// <summary>
/// 因为appName字段多写成了appName1所以修改不会成功
/// </summary>
public Int32 UpdateFalse(string appName)
{
try
{
using (var conn = GetInstance())
{
string sql = "update aoptran set appName1='" + appName + "' where id <10 ";
var result = conn.ExecuteScalar(sql);
return result != null ? Convert.ToInt32(result) : ;
}
}
catch (Exception ex)
{
return ;
}
}
namespace TranAopRealProxy.Aop
{
/// <summary>
/// RealProxy is a abstract class, which is a class in Framework to provide the function about base proxy.
/// The Invoke method like the hook of MFC, it intercept the message, inject the custom logic and generate a new message
/// for system to performance.
/// </summary>
class AOPRealProxy : RealProxy, IProxyDI
{
private MarshalByRefObject _target = null;
private IInterception _interception = null; public AOPRealProxy(Type targetType, MarshalByRefObject target)
: base(targetType)
{
_target = target;
_interception = new NullInterception();
} /// <summary>
/// Overridden the method "Invoke" of the base class, invokes the method that is specified
// in the provided System.Runtime.Remoting.Messaging.IMessage on the remote
// object that is represented by the current instance.
/// </summary>
/// <param name="msg">A System.Runtime.Remoting.Messaging.IMessage that contains a System.Collections.IDictionary
// of information about the method call.
// </param>
/// <returns>The message returned by the invoked method, containing the return value and
// any out or ref parameters.
// </returns>
public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
{
IMethodReturnMessage methodReturnMessage = null;
IMethodCallMessage methodCallMessage = msg as IMethodCallMessage;//Check whether the message is method call message.
if (methodCallMessage != null)
{
IConstructionCallMessage constructionCallMessage = methodCallMessage as IConstructionCallMessage;
if (constructionCallMessage != null)
{
RealProxy defaultProxy = RemotingServices.GetRealProxy(_target);
defaultProxy.InitializeServerObject(constructionCallMessage);
methodReturnMessage = EnterpriseServicesHelper.CreateConstructionReturnMessage(constructionCallMessage, (MarshalByRefObject)GetTransparentProxy());
}
else
{
_interception.PreInvoke();
try
{
methodReturnMessage = RemotingServices.ExecuteMessage(_target, methodCallMessage);
}
catch
{
}
if (methodReturnMessage.Exception != null)
{
_interception.ExceptionHandle();
}
else
{
_interception.PostInvoke();
}
}
}
return methodReturnMessage;
} #region IProxyDI Members /// <summary>
/// Dependency injection the interception into proxy class.
/// </summary>
/// <param name="interception">The interception.</param>
public void InterceptionDI(IInterception interception)
{
_interception = interception;
} #endregion
}
}
namespace TranAopRealProxy.Aop
{
/// <summary>
/// Description of AOPProxyAttribute.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class AOPProxyAttribute : ProxyAttribute
{
private IInterception _interception;
public Type Interception
{
get
{
return _interception.GetType();
}
set
{
IInterception interception = Activator.CreateInstance(value) as IInterception;
_interception = interception;
}
}
public AOPProxyAttribute()
{
_interception = new NullInterception();
}
public override MarshalByRefObject CreateInstance(Type serverType)
{
MarshalByRefObject target = base.CreateInstance(serverType);
AOPRealProxy aopRealProxy = new AOPRealProxy(serverType, target);
aopRealProxy.InterceptionDI(_interception);
return aopRealProxy.GetTransparentProxy() as MarshalByRefObject;
}
}
}
using System; namespace TranAopRealProxy.Aop
{
/// <summary>
/// Description of IInterception.
/// </summary>
public interface IInterception
{
/// <summary>
/// Pre the method invoke.
/// </summary>
void PreInvoke(); /// <summary>
/// Post the method invoke.
/// </summary>
void PostInvoke(); /// <summary>
/// Handling the exception which occurs when the method is invoked.
/// </summary>
void ExceptionHandle();
}
}
using System;
using System.Collections.Generic;
using System.Text; namespace TranAopRealProxy.Aop
{
interface IProxyDI
{
void InterceptionDI(IInterception interception);
}
}
//
// Authors:
// Xiaoliang Pang (mailto:mv@live.cn)
//
// Copyright (c) 2010 Landpy Software
//
// http://www.cnblogs.com/pangxiaoliang
//
using System;
using System.Collections.Generic;
using System.Text; namespace TranAopRealProxy.Aop
{
/// <summary>
/// Null Object pattern for interception.
/// </summary>
public class NullInterception : IInterception
{ #region IInterception Members /// <summary>
/// Before invoke the real instance to do something.
/// </summary>
public virtual void PreInvoke()
{
// Do nothing.
} /// <summary>
/// End invoke the real instance to do something.
/// </summary>
public virtual void PostInvoke()
{
// Do nothing.
} /// <summary>
/// Handling the exception which occurs when the method is invoked.
/// </summary>
public void ExceptionHandle()
{
// Do nothing.
} #endregion }
}
using System;
using System.Collections.Generic;
using System.Text; namespace TranAopRealProxy.Aop
{
public class ProxyFactory
{
public static T CreateProxyInstance<T>(IInterception interception) where T : new()
{
Type serverType = typeof(T);
MarshalByRefObject target = Activator.CreateInstance(serverType) as MarshalByRefObject;
AOPRealProxy aopRealProxy = new AOPRealProxy(serverType, target);
aopRealProxy.InterceptionDI(interception);
return (T)aopRealProxy.GetTransparentProxy();
}
}
}
using System.Text;
using System.Threading.Tasks;
using TranAopRealProxy.Aop;
using System.Transactions;
namespace TranAopRealProxy.Aop
{
/// <summary>
/// The interception of the AOP for trasaction.
/// </summary>
class Transaction : IInterception
{
#region IInterception Members TransactionScope tran = null;
public void ExceptionHandle()
{
tran.Dispose();
}
public void PostInvoke()
{
tran.Complete();
tran.Dispose();
}
public void PreInvoke()
{
tran = new TransactionScope();
}
#endregion
}
}
public class Logic : BaseTran
{
/// <summary>
/// 回滚
/// </summary>
public void ActionFalseRollBack()
{
DoDB db = new DoDB();
db.UpdateTrue("abc");
int isSuccess= db.UpdateFalse("defg");
if (isSuccess <=)
{
throw new Exception("苍天啊,大地啊,回滚吧。");
}
}
/// <summary>
/// 提交
/// </summary>
public void ActionFalseRollBack1()
{
DoDB db = new DoDB();
db.UpdateTrue("abc");
db.UpdateTrue("abc234");
}
}
总结
AOP在.net中还有体现,比如mvc的过滤器。也有很多第三方的插件供我们使用,比如:postsharp,castle.net等,大家可以了解学习下。如果你想把这里的透明代理与真实代理学透彻,也推荐阅读.Net本质论中的高级方法。同时也欢迎大家加入左上方群,我们一起探讨学习。
.Net中的RealProxy实现AOP的更多相关文章
- Castle框架中的IOC和AOP机制
反转控制(IOC)和面向切面编程(AOP)技术作为当前比较流行的技术,其优势已受到广泛关注,但是这两项新技术在实际项目上的应用研究却很落后,而且在.NET平台下实现这两项技术没有形成可以广泛套用的框架 ...
- 在C#中使用CastleDynamicProxy 实现AOP
原文链接:Aspect Oriented Programming (AOP) in C# using CastleDynamicProxy 本文主要展示在C#中如何使用Castle Dynamic ...
- 理解Spring中的IOC和AOP
我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式 IOC就是典型的工厂模式,通过ses ...
- 详谈 Spring 中的 IOC 和 AOP
这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置. Spring 简介 Spring 是一个开源的轻量级的企业 ...
- Spring中基于xml的AOP
1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...
- .Net基于RealProxy实现AOP
一.概述 关于AOP(面向切面编程)还是先讲一个日常经常碰到的场景"错误日志的记录",一般来说我们编码的时候想记录错误日志都是用try..catch来进行捕捉和记录,慢慢的你会发现 ...
- Spring中的IOC\DI\AOP等概念的简单学习
IoC(Inversion of Control,控制反转).这是spring的核心,贯穿始终, 所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.Spr ...
- Spring AOP报错处理 Can not set field to $Proxy 在spring中使用事物或AOP遇到的错误
[转] 解决方法: http://forum.springsource.org/showthread.php?85016-IllegalArgumentException-with-Applicati ...
- SpringMVC中对Controller使用AOP
转自http://usherlight.iteye.com/blog/1306111 正确配置spring aop,在controller中使用AOP 在controller中使用AOP的问题主要在于 ...
随机推荐
- 从中间件的历史来看移动App开发的未来
在移动开发领域我们发现一个很奇怪的现象:普通菜鸟新手经过3个月的培训就可以拿到 8K 甚至上万的工作:在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资.不知道大家是否想过:移动应用开 ...
- 传播正能量——做一个快乐的程序员
引子 今天在博客园看到施瓦小辛格的文章我们搞开发的为什么会感觉到累,顿时有感而发.自己本来不擅长写文章,更不擅长写这种非技术性的文章,但是在思绪喷薄之际,还是止不住有很多话要说.针对从客观上说&quo ...
- BootStrap_02之全局样式及组件
1.BootStrap指定的四种屏幕尺寸: ①超大PC屏幕--lg(large):w>=1200px: ②中等PC屏幕--md(medium):1200px>w>=992px: ③P ...
- Android 剪贴板详解
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Clipboard 如本文有助于你理解 Android 剪贴板,不妨给我一个 Star.对于码农而言, ...
- ubuntu系统下如何修改host
Ubuntu系统的Hosts只需修改/etc/hosts文件,在目录中还有一个hosts.conf文件,刚开始还以为只需要修改这个就可以了,结果发现是需要修改hosts.修改完之后要重启网络.具体过程 ...
- vue入门学习(基础篇)
vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...
- .Net Core上用于代替System.Drawing的类库
目前.Net Core上没有System.Drawing这个类库,想要在.Net Core上处理图片得另辟蹊径. 微软给出了将来取代System.Drawing的方案,偏向于使用一个单独的服务端进行各 ...
- jQuery的属性
The Write Less , Do More ! jQuery的属性 1. attr(name|properties|key,value|fn) : 设置或返回被选元素的属性值 ①获取属性 < ...
- 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型
前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.
- NSStringCompareOptions
typedefNS_OPTIONS(NSUInteger, NSStringCompareOptions) { NSCaseInsensitiveSearch = 1, //不区分大小写比较 N ...