• 小题大作:.Text中恶意脚本过滤的新方法


    这篇文章是关于.Text如何过滤恶意脚本的思考文章的继续。
    我下面所要讲的实现方法,实际上是A Taste of AOP from Solving Problems with OOP and Design Patterns 一文中设计思想的实际应用。实现的原理是:拦截对对象的属性的访问, 在属性返回之前,对属性值进行过滤。
    本想好好写一下这篇文章,可测试成功后,急于想把成功与大家分享,再加上成功后的兴奋,竟然感觉脑子里乱七八糟,不知写什么好,算了,先将代码贴出来给大家看看,这样也正好看看大家能不能通过我的代码理解我的实现方法,验证一下我写的代码的可读性。欢迎大家针对我的代码展开批评与讨论:

    FilterRealProxy类:一个真实代理, 拦截它所代理对象中方法的返回值,并对需要过滤的返回值进行过滤。

    public class FilterRealProxy:RealProxy

         {

             private MarshalByRefObject target;

             public FilterRealProxy(MarshalByRefObject target):base(target.GetType())

             {

                  this.target=target;   

             }

     

             public override IMessage Invoke(IMessage msg)

             {

                  IMethodCallMessage callMsg=msg as IMethodCallMessage;

                  IMethodReturnMessage returnMsg = RemotingServices.ExecuteMessage(target,callMsg);

                  if(this.IsMatchType(returnMsg.ReturnValue))//检查返回值是否为String,如果不是String,就没必要进行过滤

                  {

                       string returnValue=this.Filter(returnMsg.ReturnValue.ToString(),returnMsg.MethodName);           

                       return new ReturnMessage(returnValue,null,0,null,callMsg);

                  }

                  return returnMsg;
         }

     

             protected string  Filter(string ReturnValue,string MethodName)

             {

                  MethodInfo methodInfo=target.GetType().GetMethod(MethodName);

                  object[] attributes=methodInfo.GetCustomAttributes(typeof(StringFilter),true);

                  foreach (object attrib in attributes)

                  {

                       return FilterHandler.Process(((StringFilter)attrib).FilterType,ReturnValue);

                      

                  }

                  return ReturnValue;

             }

     

            

              protected bool IsMatchType(object obj)

             {

                  return obj is System.String;

             }

         }


    StringFilter类:自定义属性类, 定义目标元素的过滤类型 

    public class StringFilter:Attribute

         {

             public StringFilter(FilterType filterType)

             {

                  this._filterType=filterType;

             }

     

              protected FilterType _filterType;

     

             public FilterType FilterType

             {

                  get

                  {

                       return _filterType;

                  }

             }

     

         }



    枚举类:用于指定过滤类型,例如:对script过滤还是对html进行过滤?

    [Flags()]

         public enum FilterType

         {

             Script = 1,

             Html =2

         }


    过滤处理类:根据过滤类型,调用相应的过滤处理方法。

    public class FilterHandler

         {

             private FilterHandler()

             {

                 

             }

     

             public static string Process(FilterType filterType,string filterContent)

             {

                  switch (filterType)

                  {

                       case FilterType.Script:

                           return FilterScript(filterContent);

                           break;

                       case FilterType.Html:

                           return FilterHtml(filterContent);

                           break;

                       default:

                           return filterContent;

                           break;

                  }

     

             }

     

             public static string FilterScript(string content)

             {

                  string regexstr=@"(?i)<script([^>])*>(\w|\W)*</script([^>])*>";

                  return Regex.Replace(content,regexstr,string.Empty,RegexOptions.IgnoreCase);

             }

     

             public static string FilterHtml(string content)

             {

                  string newstr=FilterScript(content);

                  string regexstr=@"<[^>]*>";

                  return Regex.Replace(newstr,regexstr,string.Empty,RegexOptions.IgnoreCase);

             }

     

     

         }

    实体类:该实体类必须从MarshalByRefObject继承,所以被过滤的实体类不能再从其他类继承或实现接口,这是使用透明代理的局限性。

    public class Entry : MarshalByRefObject

         {

             public Entry()

             {

             }

            

             public static Entry CreateInstance()

             {

                  Entry entry=new Entry();

                  RealProxy realProxy = new FilterRealProxy(entry);

                  object transparentProxy = realProxy.GetTransparentProxy();

                  return (Entry)transparentProxy;

                 

             }

     

            private string _body;

            

             public virtual string Body

             {

                  [StringFilter(FilterType.Scrtipt)] //通过StringFilter设置实体类的属性是否需要过滤,以及指定过滤的方法

                  get{return _body;}

                  set{_body = value;}

             }

     

         }



    NUnit测试代码:

        

             [Test]

             public void EntryTest()

             {

                  Entry en=Entry.CreateInstance();

                  System.IO.StreamReader sr=new System.IO.StreamReader("script.txt");//得到一个含有script脚本的字符串

                  en.Body=sr.ReadToEnd();

                  Console.Write(en.Body);

             }

    测试结果是得到了一个不含script的字符串。

  • 相关阅读:
    C# 设计模式-抽象工厂模式
    C# 设计模式-工厂方法模式
    C# 设计模式-简单工厂模式
    C# 设计原则-迪米特法则(最少知识原则)
    C# 设计原则-接口隔离原则
    阻止右击事件并更改为自定义导航栏;
    今日头条滚动新闻版块特效
    抓包工具
    查看页面加载速度
    插件那点事
  • 原文地址:https://www.cnblogs.com/dudu/p/2720.html
Copyright © 2020-2023  润新知