关于.Text如何过滤恶意脚本的思考

  3月8日博客园出现首页不显示内容的问题,是由于.Text程序没有对用户显示名称进行脚本过滤造成的。.Text中,还有不少地方存在这样的问题。实际上,每个用户输入的并且会在页面上显示的内容都要进行脚本过滤,不然难免安全隐患。
   .Text中如何对用户输入的内容进行过滤的呢?主要通过EntryValidationHandler与CommentFormatHandler两个类来完成的,它们在数据被提交到数据库之前对数据进行检查与处理。
   EntryValidationHandler主要是检查,发现不合法的内容就进行错误提示,不向数据库提交,但.Text的检查方法好像有点问题,从Word复制过来的html内容,比如:从VS.NET复制到Word再复制.Text中,.Text总是无法通过检查,没办法,博客园为了方便大家,只能自己写代码处理,现在只是简单过滤掉script。
   CommentFormatHandler主要作用是将评论中html标记转换成文本,这样就避免了评论中的恶意内容。

      显然,.Text中对恶意脚本的处理存在不足:
     1、在EntryValidationHandler中,只对文章的内容进行检查,在.Text中文章用一个Entry实体类来表示,.Text寻Enrty.Body进行了检查,实际上Enry类的很多属性也要进行恶意脚本检查与过滤。
     2、.Text中还有一个重要的实体类BlogConfig,BlogConfig中的很多数据是要用户去维护的,所以对BlogConfig的某些属性进行检查也是必要的,博客园出现的问题,也就是由于.Text没有这个实体类进行检查。
     3、博客园中增加了高级评论功能,所以显示评论时,要允许html代码,而原来的.Text中是不允许html的(所以不必担心恶意内容),但现在博客园的程序必须对评论进行处理,实际上评论也是用Enry类表示,只要对Enry类进行处理就解决了评论的问题。

     应该如何有效过滤恶意脚本?我想过三种方法:
     1、当用户在表单中输入数据提交时,进行检查。但这种方法无法对Blog桌面工具发表的文章进行检查,这类文章还要单独处理。
     2、在显示时进行过滤,这种很明显,既麻烦又容易出现问题,只要一处忘了进行过滤,就会前功尽弃。
     3、在数据提交到数据库之前进行过滤,.Text就是采用这种方法,但不足之处是在每个数据更新操作之前,都要进行检查。

   我觉得这三种方法都不是很有效的方法,好的方法应该在一个统一的地方对进行恶意内容进行过滤。为何不把目光关注到这两个实体类?只要对这两个实体类进行检查与过滤,那不就解决问题了吗?既然所有的操作都是围绕这两个实体类,只要我们对这两个实体类中的相关属性进行检查与过滤,那就不担心其他地方会出现未过滤的内容。虽然.Text有的地方显示数据时,没有访问实体类,但所有更新数据的操作都是通过实体类传递数据的。我现在想到的一种方法是在实体类相关属性的Get中进行处理,在Get返回之前,对属性值进行过滤。这是一种简单有效的方法,但不是完美的方法,我们要尽可能减少对实体类的修改。能不能用设计模式去解决这个问题,用DECORATOR模式?很多模式是针对接口与方法的,而这里的实体类是用于表示数据的,全是属性,没有方法。JGTM的文章A Taste of AOP from Solving Problems with OOP and Design Patterns 也是讨论相关问题的,文章我还没全部理解,但那也是针对在调用对象的方法之前进行附加的处理,而对属性该如何处理?

    请大家提供一些好的思路,或者有什么简单的办法,请指点!
    文章有不妥之处,请见谅,毕竟出于一个.NET技术水平不高的作者之手。

posted on 2004-03-09 16:38 dudu 阅读(4907) 评论(25)  编辑 收藏 网摘 所属分类: .Text相关

评论

#1楼 2004-03-09 16:55 小春

实际上可以直接利用server.htmlencode(内容)将所有的<>转换成相应的<=&lt; >=&gt; 然后修改的时候就可以server.HtmlDecode(内容)来下午解码就可以了。也省去了replace来替代。

不知道这样子行吗?
  回复  引用    

#2楼 2004-03-09 16:56 小春

你可以找一下这方面的资料。上面的讲评我有几个字写错了。不好意思:)   回复  引用    

#3楼 2004-03-09 17:05 dudu

html是要显示的, 目前主要是过滤script代码。   回复  引用    

#4楼 2004-03-09 17:11 韩磊[未注册用户]

我认为在Entry实体类的更新操作中进行过滤是比较好的方式。   回复  引用    

#5楼 2004-03-09 17:34 JGTM'2004 [MVP][未注册用户]

AOP适用于普遍情况,针对性的特别情况(尤其在有代码的情况下)不需要使用这些复杂技术,看来是被我误导了。:)

这种情况可以考虑在Get/Set方法内部返回/保存内容之前调用一个ValidateContent()虚方法(TEMPLATE METHOD),把对内容的验证逻辑潜入到已有逻辑中(并可以在子类中重载改变),或者如果对所有子类的验证逻辑都是一致的话,不实现为虚方法也可以。

BTW: 属性其实就是一对儿方法(getter/setter),没有什么本质的区别。
  回复  引用    

#6楼 2004-03-09 17:36 JGTM'2004 [MVP][未注册用户]

小春的方法看着简单,其实是把所有HTML都枪毙了,这还不如把内容都用XMP置标括起来呢。;)   回复  引用    

#7楼 2004-03-09 18:19 韩磊[未注册用户]

实际上用Decorate模式是恰当的。创建一个名为EntryDecorate(由于要求比较简单,用Concret Decorate就好了)的类,在需要的时候,调用该类的RemoveHtml方法,实现过滤。在普通的情况下,这个EntryDecorate类是透明的。这样可以有很好的灵活性。   回复  引用    

#8楼 2004-03-09 19:07 dudu

如果用Decorate模式, 所有需要被过滤的实体类都要有一个共同的接口,并实现这个共同的接口, 而实体类去实现这个接口, 显得有点多余。   回复  引用    

#9楼 2004-03-09 19:24 dudu

现在假如对Entry类的每个属性都要过滤恶意脚本, 如果通过Get/Set在增加一个方法调用来实现, 很麻烦, 如果有很多实体类, 对每个实体的属性都要进行更改。是不是建立一个专门进行过滤的类, 在这个类中定义过滤策略, 对哪些类的哪些属性进行过滤, 这个类相当于一个代理, 在对实体类的属性进行访问之前, 这个代理类负责检查、过滤。   回复  引用    

#10楼 2004-03-09 19:35 dudu

是不是可以用RealProxy来实现, 在RealProxy的Invoke中对属性进行过滤。我试试看!   回复  引用    

#11楼 2004-03-09 23:16 JGTM'2004 [MVP][未注册用户]

过滤策略可以结合自定义属性定义甚至连接到外部的配置数据(可以考虑使用Regex),用RealProxy是可行的,但对于这个场合不一定是最好的。这种情况下需要改变对象的行为需要用的技术还是传统的重构技术——尤其在你有源码的情况下。

不过——dudu的实践精神我是十分鼓励和赞赏的!什么事情你不亲自做一下你怎么知道就不行或者不好呢?所以还是鼓励大家遇到问题的时候多动手、多动脑!GJGJ…… :)
  回复  引用    

#12楼 2004-03-10 11:32 韩磊[未注册用户]

不,不需要共同接口。按照Decorate的原义,直接在需要时调用Decorate类的方法处理就行了。其实,你提到的过滤类,就是一种Decorate模式了啊。   回复  引用    

#13楼 2004-03-10 16:59 JGTM'2004 [MVP][未注册用户]

@韩磊:

不需要共同接口也得有一个共同基类,而当这个基类中都是抽象方法的时候,实际上就蜕变为了接口。你再仔细看看设计模式,client是不可以直接调concrete component或decorator的(不存在concrete decorator的概念,concrete component和decorator实际上是在一个层次上的,只是其功能分工不同罢了),client只需要依赖一个抽象的component,而这个就是所谓的提取出来的公共基类——或者说是concrete component和decorator共同遵循的语义——也就是接口。
  回复  引用    

#14楼 2004-03-10 18:17 JustinS

-_-b 学习ing   回复  引用    

#15楼 2004-03-10 18:34 dudu

在JGTM'2004[MVP]的指导下, 已经成功通过重载RealProxy的Invoke方法, 对属性的返回值进行过滤 。如何提供配置信息给这个RealProxy, 让它只对需要过滤的属性进行过滤, 用一个Xml文件?我现在准备采用的方法是通过一个自定义属性来判断一个实体类的属性是否需要过滤, 就像NUnit中的[test], 需要过滤的属性只要在相应的属性前加一个标记,比如:[FilterScript]。   回复  引用    

#16楼 2004-03-10 20:52 JGTM'2004 [MVP][未注册用户]

@dudu:

You're right onto the way to go...go ahead and have fun! I'll be always here to provide my emotional and technical support to you! :)
  回复  引用    

#17楼 2004-03-11 08:15 小春

SORRY,我不看清楚是意思,只是以为将html的恶意代码解决,没有考虑页面还是要html样式的
呵呵。 理解错误了
  回复  引用    

#18楼 2004-03-11 10:23 koffer

实践精神!
绝对赞同,真正的勇士是敢于接受任何挑战的!
向dudu学习!

而且软件就应该一丝不苟,可惜我还没有这个水平!还好有各位老大JGTM'2004,dudu照着
  回复  引用    

#19楼 2004-03-15 09:38 Visual Icers

学习!   回复  引用    

#20楼 2004-03-22 16:35 王答

<b>学习</b>   回复  引用    

#21楼 2004-07-21 17:19

我每次拨号上网都会提示有恶意脚本,该怎办呢?我是新手这方面一点不懂请高手们指点一下!   回复  引用    

#22楼 2004-08-19 18:58 无常

我也来测试   回复  引用    

#23楼 2005-03-22 18:41 killren[未注册用户]

有点看不懂,但还是学习一下   回复  引用    

#24楼 2008-08-27 10:35 xuexi_0123[未注册用户]

<script>alert('学习');</script>   回复  引用    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 2596




相关文章:

相关链接:

导航

公告

人生的真正价值在于从何种程度与何种意义上摆脱自我!
明天继续更新评论功能
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

统计

与我联系

搜索

 

常用链接

留言簿

随笔分类

随笔档案

新闻分类

相册

HJ

朋友的博客

网站收藏

小组

友情链接

最新随笔

最新评论

阅读排行榜

评论排行榜

60天内阅读排行