<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>nullTao | 净空无道 | Blog - TranslatioN</title>
    <link>http://blog.nulltao.net/</link>
    <description>如果死真的是种解脱，那么愿死者有他的天堂，愿生者有他的寄托。但愿在宇宙的深处真有一处天堂，有一天当我们在经历生死契阔之后，还有一个地方在等待着我们的——重逢。</description>
    <dc:language>en</dc:language>
    <admin:errorReportsTo rdf:resource="mailto:nulltao@gmail.com" />
    <generator>Serendipity 1.3 - http://www.s9y.org/</generator>
    <pubDate>Wed, 05 Nov 2008 10:01:27 GMT</pubDate>

    <image>
        <url>http://blog.nulltao.net/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: nullTao | 净空无道 | Blog - TranslatioN - 如果死真的是种解脱，那么愿死者有他的天堂，愿生者有他的寄托。但愿在宇宙的深处真有一处天堂，有一天当我们在经历生死契阔之后，还有一个地方在等待着我们的——重逢。</title>
        <link>http://blog.nulltao.net/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Read It Later 集成到 Google Reader</title>
    <link>http://blog.nulltao.net/archives/102-Read-It-Later-Google-Reader.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/102-Read-It-Later-Google-Reader.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=102</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=102</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;洒家阅读新闻用的两个最重要的工具：Read It Later 和 Google Reader 终于能够直接集成了。实在是美哉。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;http://www.readwriteweb.com/archives/read_it_later_comes_to_google_reader.php&quot; target=&quot;_blank&quot;&gt;Read It Later Comes To Google Reader&lt;/a&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img
	src=&quot;http://www.readwriteweb.com/images/readitlater_logo.png&quot;
	class=&quot;content-block-fix&quot; /&gt;&lt;a href=&quot;http://readitlaterlist.com/&quot;
	target=&quot;_blank&quot;&gt;Read It Later&lt;/a&gt;，一个流行的 Firefox 插件，最近发布了升级版本，该版本给 &lt;a
	href=&quot;http://reader.google.com&quot; target=&quot;_blank&quot;&gt;Google Reader&lt;/a&gt;
增加了一些新功能。这个新扩展同时兼容 Firefox 和 IE，这个新扩展让你能够在阅读你所订阅的 RSS
种子的时候勾选出需要稍后再做详细阅读的新闻，以此来加快你的浏览速度。 你还能够使用任何浏览器访问到这些你想稍后阅读的这些新闻，不管是在家里的
Firefox，在单位的 IE，甚至你的 iPhone 手机都可以。&lt;/p&gt;
&lt;p&gt;&lt;img align=&quot;left&quot;
	src=&quot;http://www.readwriteweb.com/images/readitlater_2.gif&quot;
	class=&quot;default-content-margin&quot; /&gt;这个升级版的 &lt;a
	href=&quot;http://readitlaterlist.com/&quot; target=&quot;_blank&quot;&gt;Read It Later&lt;/a&gt;
扩展给你的 Google Reader 的种子列表增加了一个 Greasemonkey-esque
功能，就是在每个新闻条目的旁边，星标的右边增加一个对勾符号。在你浏览你的订阅的时候，你勾选上的帖子会自动增加到你的阅读列表中——你可以随时在 &lt;a
	href=&quot;http://readitlaterlist.com&quot; target=&quot;_blank&quot;&gt;readitlaterlist.com&lt;/a&gt;
网站上访问到你保存的阅读列表。通过内置的离线浏览功能，你还能在准备要离开网络的时候，下载一系列文章供你以后阅读——比如说当你乘飞机旅行的时候。&lt;/p&gt;

&lt;p&gt;如果你使用书签插件来管理你的阅读列表，那么现在你有更多的选项供你定制。你可以使用“普通”模式或者“紧凑”模式查看阅读列表、选择每页显示的条目数、是否在侧边栏打开阅读列表、以及是否启用上下文关联菜单和附加的工具栏按钮。&lt;/p&gt;

&lt;p&gt;&lt;img align=&quot;right&quot;
	src=&quot;http://www.readwriteweb.com/images/readitlater_1.gif&quot;
	class=&quot;default-content-margin&quot; /&gt;不过，新加的功能中最棒的就是可以按照 &lt;a
	href=&quot;http://postrank.com/&quot; target=&quot;_blank&quot;&gt;PostRank&lt;/a&gt;
对阅读列表进行排序。我们在读写网&lt;a
	href=&quot;http://www.readwriteweb.com/archives/first_look_aiderss_feed_filtering.php&quot;
	target=&quot;_blank&quot;&gt;好几次&lt;/a&gt;都&lt;a
	href=&quot;http://www.readwriteweb.com/archives/aiderss_funding.php&quot;
	target=&quot;_blank&quot;&gt;非常关注&lt;/a&gt;这个曾经名为 AideRSS 的功能。在启用 PostRank
后，你的阅读列表会智能的按照流行度进行过滤。 有几种方式给一个帖子打分，包括该帖子收到的评论数、在美味书签上被标记的次数，被 digg
的次数，以及被引用的连接数。 你现在可以按照帖子的重要程度来浏览你的阅读列表，这对那些被过量的信息所困扰的人特别有用。&lt;/p&gt;
&lt;p&gt;该插件还有一些其他的改进，例如升级了的隐私控制、现有功能的更强大技巧等，这些改进让 Read It Later
逐渐成你的浏览器中一个重要的插件，不管你用的是 Fireofox 还是 IE。 现在，我们就只需要的就是能够在 iPhone
上使用的书签插件，那就就齐活了。&lt;/p&gt;

&lt;p&gt;&lt;embed width=&quot;425&quot; height=&quot;344&quot;
	type=&quot;application/x-shockwave-flash&quot; wmode=&quot;transparent&quot;
	allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;never&quot;
	src=&quot;http://www.youtube.com/v/mLNfsLpM8zo&amp;amp;hl=en&amp;amp;fs=1&quot;
	class=&quot;content-block-fix&quot; /&gt;&lt;span class=&quot;link popout&quot;
	title=&quot;Click to open in a new window&quot;&gt;Popout&lt;/span&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 05 Nov 2008 17:06:37 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/102-guid.html</guid>
    <category>google</category>
<category>readitlater</category>
<category>rww</category>
<category>translation</category>

</item>
<item>
    <title>真实世界让你很沮丧吗？IBM 邀请你到超越时空的紫禁城一游。 </title>
    <link>http://blog.nulltao.net/archives/101-IBM.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/101-IBM.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=101</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=101</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;原文：&lt;a href=&quot;http://www.techcrunch.com/2008/10/10/real-world-got-you-down-ibm-invites-you-to-a-virtual-forbidden-city/&quot; target=&quot;_blank&quot;&gt;Real World Got You Down? IBM Invites You To A Virtual Forbidden City.&lt;/a&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;http://www.techcrunch.com/wp-content/uploads/2008/10/forbidden-city-ghosts.png&quot; target=&quot;_blank&quot;&gt;&lt;img width=&quot;515&quot; height=&quot;287&quot; title=&quot;forbidden-city-ghosts&quot; alt=&quot;&quot; src=&quot;http://www.techcrunch.com/wp-content/uploads/2008/10/forbidden-city-ghosts.png&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;想去中国游览紫禁城又买不起机票？现在，你只要有台计算机就行了。IBM——虚拟世界最忠实的信徒——和中国故宫博物院共同把这个占地 178 英亩的紫禁城在虚拟世界里重现。在三年时间里，他们非常细致的重建了所有的建筑物和数以千计的重要文物，现在，“&lt;a href=&quot;http://www.beyondspaceandtime.org/&quot; target=&quot;_blank&quot;&gt;超越时空的紫禁城&lt;/a&gt;”已经可供下载(有 Windows、Mac 和 Linux 版)。这个软件可以免费下载，不过先提醒你，Mac 版的可是一个实实在在的 275M 的安装包。&lt;/p&gt;
&lt;p&gt;当你进去后，你能够选择你的形象、穿上清朝的服装、进行虚拟的浏览、和计算机控制的角色玩耍、查找地图、浏览建筑物和里面的文物，你还可以点击这些建筑物或者文物以得到进一步信息。这个虚拟世界构建在名为 Torque 的游戏平台，这个游戏平台来自 &lt;a href=&quot;http://www.garagegames.com/&quot; target=&quot;_blank&quot;&gt;Garage Games&lt;/a&gt;。（我估计是因为 OpenSim 不够好，因为没有评论说虚拟时空紫禁城时候会和第二人生进行&lt;a href=&quot;http://www.techcrunch.com/2008/07/08/ibm-and-second-life-announce-interoperability-project-but-bridging-virtual-worlds-is-the-wrong-answer/&quot; target=&quot;_blank&quot;&gt;互动&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;如果你想找个地方躲避现在金融风暴，但是有没钱真的出去旅游的话，那么你可以来 IBM 的超越时空紫禁城里闲逛上几个钟头。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/uploads/2008/10/forbidden-city-go.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/uploads/2008/10/forbidden-city-plans.png&quot;/&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 13 Oct 2008 11:21:39 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/101-guid.html</guid>
    <category>techcrunch</category>
<category>translation</category>
<category>virtualworld</category>

</item>
<item>
    <title>地图聚合的数据格式前三名：KML、GeoRSS 和 GeoJSON</title>
    <link>http://blog.nulltao.net/archives/95-KMLGeoRSS-GeoJSON.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/95-KMLGeoRSS-GeoJSON.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=95</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=95</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;原文地址：&lt;a href=&quot;http://blog.programmableweb.com/2008/08/27/3-top-data-formats-for-map-mashups-kml-georss-and-geojson/&quot; target=&quot;_blank&quot;&gt;3 Top Data Formats for Map Mashups: KML, GeoRSS and GeoJSON&lt;/a&gt;。&lt;/p&gt;
&lt;hr /&gt;

&lt;p&gt;&lt;a title=&quot;ProgrammableWeb&quot; href=&quot;http://www.programmableweb.com/mapping&quot;&gt;&lt;img src=&quot;http://www.programmableweb.com/images/apis/at22.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt; 随着地图聚合给最终用户提供的一系列更广泛的工具和应用程序，它在完善程度和功能性两方面逐渐走向成熟。 因此，我们需要一些预定义好的方法在传统的地理空间数据和新一代的&lt;a href=&quot;http://www.programmableweb.com/mapping&quot;&gt;地图聚合&lt;/a&gt;之间交换、发布这些地理空间数据，并且使用一种对 web 友好的方式使用这些数据。&lt;/p&gt;
&lt;p&gt;为了满足这种需求，出现了一些新的地理空间数据格式，这能够让更大范围的用户和开发者来聚合地理相关的信息。 下面是当前可供从事地理信息聚合的开发者使用的三种主要数据格式的一个概括：&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;http://code.google.com/apis/kml/&quot;&gt;KML&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;你知道 &lt;a href=&quot;http://earth.google.com&quot;&gt;Google 地球&lt;/a&gt;的前身，那个流行的名为 Keyhole 的三维地球浏览器吗？ 如果你知道，那么这个基于 XML 的，Google 地球自己的文件格式被叫做 &lt;a href=&quot;http://code.google.com/apis/kml/&quot;&gt;KML&lt;/a&gt;，意为 Keyhole 标记语言，就不值得惊讶了。 在地理空间相关的网站上，KML 无处不在，KML 支持从类似 &lt;a href=&quot;http://www.programmableweb.com/api/google-maps&quot;&gt;Google 地图&lt;/a&gt;、微软的&lt;a href=&quot;http://www.programmableweb.com/api/microsoft-virtual-earth&quot;&gt;虚拟地球&lt;/a&gt;这样商业化的地图 API 和 &lt;a href=&quot;http://www.programmableweb.com/api/openlayers&quot;&gt;OpenLayers&lt;/a&gt; 这样开源的地图 API 中导入、导出数据。 今年早些时候，Google 把 KML 作为一种开放标准发布，并且被开放地理空间联盟 (OGC) 采用。 你可以研读&lt;a href=&quot;http://code.google.com/apis/kml/documentation/kmlreference.html&quot;&gt;最新的 KML 规范&lt;/a&gt; (当前是 2.2 版) 或者学习如何让 KML 与 &lt;a href=&quot;http://code.google.com/apis/maps/documentation/reference.html#GGeoXml&quot;&gt;Google 地图 API&lt;/a&gt;、&lt;a href=&quot;http://blogs.msdn.com/keithkin/archive/2007/11/20/virtual-earth-api-adding-kml-or-georss-layers-to-the-map.aspx&quot;&gt;虚拟地球&lt;/a&gt;或者 &lt;a href=&quot;http://dev.openlayers.org/releases/OpenLayers-2.6/doc/apidocs/files/OpenLayers/Format/KML-js.html&quot;&gt;OpenLayers&lt;/a&gt; 集成。&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;http://georss.org/&quot;&gt;GeoRSS&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://georss.org/&quot;&gt;GeoRSS&lt;/a&gt; 提供了一种在 RSS (或者 Atom) 种子里通过特定的编码来包含地理参考信息的方法。GeoRSS 站点上说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RSS 和 Atom 作为一种发布、共享信息的方法，正在逐渐流行起来， 因此，使用互操作的方式描述位置信息，来让程序能够请求、聚合、共享、地图化地理标记过的种子变得益发重要。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;嵌入 &lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoRSS&quot;&gt;&lt;em&gt;GeoRSS&lt;/em&gt;&lt;/a&gt; 非常简单，仅仅在每个条目中增加一个类似 &lt;code&gt;&amp;lt;georss:point&amp;gt;45.256 -71.92&amp;lt;/georss:point&amp;gt; 这样的元素就行了，这里使用的是&lt;a href=&quot;http://georss.org/simple&quot;&gt;简易GeoRSS&lt;/a&gt; 格式， 如果要需要复杂完整的编码格式，可以选择支持更多的特性的 &lt;a href=&quot;http://georss.org/gml&quot;&gt;GeoRSS-GML&lt;/a&gt; 格式。这两种 GeoRSS 格式都支持基本的地理特征 (点、线、边框和多边形)。 和 KML 一样，商业化的地图 API 和开源地图 API 都支持 GeoRSS，并且主要作为导入数据的格式使用。 GeoRSS 许诺对整合内容的会有更好的支持。&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;http://geojson.org&quot;&gt;GeoJSON&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://geojson.org&quot;&gt;GeoJSON&lt;/a&gt; 是基于 JavaScript 对象表示法 (JSON)的一种新的数据格式，用来对大量的地理特征进行编码，支持的地理特征有点、线、多边形、多多边形和地理信息集合。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{ &quot;type&quot;: &quot;Point&quot;, &quot;coordinates&quot;: [43.542, -118.454] }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoJSON&quot;&gt;&lt;em&gt;GeoJSON&lt;/em&gt;&lt;/a&gt; 可以被 JavaScript 简单、快速的解析，而且 GeoJSON 还提供了一个可以很容易的进行交换的轻量级数据格式。 自从 GeoJSON 正式发表 1.0 版后，GeoJSON 的魅力逐渐增加，得到了包括 &lt;a href=&quot;http://www.programmableweb.com/api/fire-eagle&quot;&gt;FireEagle&lt;/a&gt; 和 &lt;a href=&quot;http://www.programmableweb.com/api/openlayers&quot;&gt;OpenLayers&lt;/a&gt; 在内的一些流行的 API 的支持 (但是不确定将来是否能够得到类似 Google 地图或者虚拟地球这样的商业 API 的支持)。&lt;/p&gt;
&lt;p&gt;注意 &lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoRSS&quot;&gt;&lt;em&gt;GeoRSS&lt;/em&gt;&lt;/a&gt; 和 &lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoJSON&quot;&gt;&lt;em&gt;GeoJSON&lt;/em&gt;&lt;/a&gt; 都采用创作共用授权协议授权。&lt;/p&gt;
&lt;p&gt;我们饶有兴趣的看着这些格式如何发展，而且很想知道类似 &lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoRSS&quot;&gt;&lt;em&gt;GeoRSS&lt;/em&gt;&lt;/a&gt; 和 &lt;a class=&quot;bodytag&quot; target=&quot;_blank&quot; href=&quot;http://blog.nulltao.net/articles/tag/GeoJSON&quot;&gt;&lt;em&gt;GeoJSON&lt;/em&gt;&lt;/a&gt; 这样的格式能否得到&lt;a href=&quot;http://www.programmableweb.com/apis/directory/1?apicat=Mapping&quot;&gt;地图 API&lt;/a&gt; 和地图聚合开发者的采用。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 28 Aug 2008 18:34:37 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/95-guid.html</guid>
    <category>geojson</category>
<category>georss</category>
<category>kml</category>
<category>map</category>
<category>mashup</category>
<category>translation</category>

</item>
<item>
    <title>做好准备迎接新的平台大战。Google Gears 直指微软领地</title>
    <link>http://blog.nulltao.net/archives/88-Google-Gears.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/88-Google-Gears.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=88</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=88</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;原文：&lt;a target=&quot;_blank&quot; href=&quot;http://www.techcrunch.com/2008/06/13/google-drives-towards-microsoft-and-adobe-with-gears/&quot;&gt;Get Ready For A New Platform War. Google Gears Drives Straight At Microsoft’s Profits.&lt;/a&gt;。&lt;/p&gt;
	&lt;hr /&gt;
	&lt;p&gt;&lt;img width=&quot;244&quot; height=&quot;158&quot; border=&quot;0&quot; src=&quot;http://www.techcrunch.com/wp-content/nextgenweb2.jpg&quot; alt=&quot;lame_logo&quot; style=&quot;border-width: 0px; float: left;&quot;/&gt; &lt;/p&gt;
	&lt;p&gt;&lt;a href=&quot;http://crunchbase.com/company/google&quot; target=&quot;_blank&quot;&gt;Google&lt;/a&gt; 在去年五月发布了 &lt;a href=&quot;http://www.crunchbase.com/product/google-gears&quot; target=&quot;_blank&quot;&gt;Gears&lt;/a&gt;，之后的一年里 Gears 被认为是一个小众产品，只会有很少开发者和用户用它来开发能够离线访问的 web 程序。兴许你还能回想起当年的争论：在到处都有网络连接的情况下，究竟谁需要离线访问功能，而且还没有足够的程序支持，等等。不到一年的时间，就在几周前，Google 亮出了他的王牌：&lt;a href=&quot;http://www.techcrunch.com/2008/05/28/myspace-shows-facebook-how-its-done-google-gears-to-power-messaging/&quot; target=&quot;_blank&quot;&gt;Gears 助力 MySpace 加速邮件系统&lt;/a&gt;。其实 Google 早就加入了这场提供新 web API 的比赛，但是居然一年了都没有人注意到。&lt;/p&gt;
	&lt;p&gt;将来的浏览器很可能会变成运行所有程序的虚拟机。在这种情况下，操作系统会变的透明，就像 Adobe 所作的，它的 Flash 技术是现在使用的最普遍、最统一的 web 虚拟机，而微软则要自保（它的利润的来源）了。Google 不隐瞒他们想瞄准并且攻击微软的野心，他们知道，要做到这点的最好方法就是上移一层把操作系统架空，让浏览器成为标准且强劲的应用程序虚拟机。&lt;/p&gt;
&lt;p&gt;很难在一片评论里表达清楚 Gears 如何改变并且增加 web 程序的功能。以前使用基于浏览器的 Javascript 脚本，&lt;a href=&quot;http://myspace.com&quot; target=&quot;_blank&quot;&gt;MySpace&lt;/a&gt; 中的一些类似邮件列表和排序、根据好友列表过滤这样的功能会让人感觉很慢，而当浏览器向服务器发送多个请求时，进度条还可能会定住，沙漏图标在不停的旋转。而现在，安装 Gears 只要在确认框点击一下并且等待几秒钟，安装之后，以前让用户抓狂的那些功能现在感觉起来就好象是浏览器自带功能一样。Google 给我们秀了一把 Gears 与 MySpace 集成后的能力，这唤醒了大部分人关注他真正的意图：不再仅是离线浏览，而是直接针对 Adobe 和微软所采取的行动。&lt;/p&gt;
&lt;p&gt;截至目前为止，Google 拥有一系列共计 &lt;a href=&quot;http://www.google.com.au/options/index.html&quot; target=&quot;_blank&quot;&gt;28 个&lt;/a&gt;基于 web 的程序, 这些程序在全世界有数百万的用户。Google 开发 web 程序的技术都是基于标准的 HTML、CSS 和 Javascript。选择 &lt;a href=&quot;http://en.wikipedia.org/wiki/Ajax&quot; target=&quot;_blank&quot;&gt;Ajax&lt;/a&gt; 仅仅是因为这是最好的解决方案，但是 Google 还要做更多以面对现实，那就是每个类似的 web 开发技术体系都是被一个&lt;a href=&quot;http://crunchbase.com/company/microsoft&quot; target=&quot;_blank&quot;&gt;直接&lt;/a&gt;的&lt;a href=&quot;http://crunchbase.com/company/adobe&quot; target=&quot;_blank&quot;&gt;竞争者&lt;/a&gt;所开发、控制。Google 对开源浏览器 &lt;a href=&quot;http://www.getfirefox.com&quot; target=&quot;_blank&quot;&gt;Firefox&lt;/a&gt; 的开发给予了强大的支持，并且支持开放 web 标准作为他们的技术体系之选。Google 这么做是因为他们的 web 程序都依赖于开放标准，Firefox 的失败会导致 Internet Explorer 复生并且把 web 的控制权拱手让给微软。&lt;/p&gt;
&lt;p&gt;以前，只用基于浏览器的 Javascript 来支持 web 程序对 Google 来说不是个问题。直到竞争者领先一步发布了他们自己的第二代 web 平台，分别是 &lt;a href=&quot;http://en.wikipedia.org/wiki/Flex&quot; target=&quot;_blank&quot;&gt;Flex/AIR&lt;/a&gt; 和 &lt;a href=&quot;http://crunchbase.com/product/silverlight&quot; target=&quot;_blank&quot;&gt;Silverlight&lt;/a&gt;，情况才发生了变化。基于 web 的程序在有了类桌面的界面和功能后能够做什么，从这一方面开说，微软和 Adobe 已经超前了一大步。用不了多久，大大小小的竞争者就会使用竞争性技术平台创建竞争性程序，那会使 Google 的产品看起来像是还停留在上个世纪九十年代的样子。&lt;/p&gt;
&lt;p&gt;留给 Google 的选择现在很明了了：要么放弃使用基于浏览器的 Javascript 和开放标准进行开发，转而接受新技术中的一种，要么继续坚持使用核心 web 技术并且发展这些技术直到成为可行的替代技术。Google 的问题是，新标准和预期的浏览器功能很快就会带来富 web 技术，但是开发那些标准的进度却如此缓慢，以至于很可能需要几年时间才能看到那些标准被广泛的应用。新的 HTML 标准，&lt;a href=&quot;http://www.techcrunch.com/2008/06/05/the-next-gen-web-html5-will-we-ever-see-a-real-standard/&quot; target=&quot;_blank&quot;&gt;HTML5&lt;/a&gt;，特别关注扩展本地浏览器对 web 程序的支持能力，在不用附加私有运行时的情况下。Google web API 的基础就是这些同样的功能以及其他的附加功能。&lt;/p&gt;
&lt;p&gt;由于标准开发的极其缓慢，导致通向更快更好，而且仍旧免费开放的 web 程序之路被堵死了，所以 Google 决定通过 Gears 自己进入这个市场。想法其实很简单：把明天的 web 技术带到今天的浏览器里。这些特定的功能大部分都来自新的 HTML5 规范，但是标准制定小组已经在上面花费了好几年。不想再等这个小组完成规范，Google 自己通过件对浏览器进行扩展，实现了这些功能并且达到了那个小组能达到的最高水平。他们宁愿在短期内抛弃标准（原话是“以后再考虑实现”）也要把他们的 web 程序带到能够对抗 Flash 和 Silverlight 的下一代标准。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.crunchbase.com/person/vic-gundotra&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;float: right;&quot; src=&quot;http://www.crunchbase.com/assets/images/resized/0001/7940/17940v1-max-250x250.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gears 有一个 30 人左右的小组开发，这个小组是 Google 内部开源小组的一部分。这个小组由 &lt;a href=&quot;http://www.crunchbase.com/person/vic-gundotra&quot; target=&quot;_blank&quot;&gt;Vic Gundotra&lt;/a&gt; 带领，再一次讽刺的转变过程中，他由微软的传教士成为 Google 的高级开发者。这个一小组开发者着手进行开发，并且保持 Google 对 Javascript 和开放浏览器虚拟机的兴趣。理论上，他们看起来很可能被大组织或者微软和 Adobe 正在投入各自平台的预算所超过。为了改变这个状况，他们把 Gears 从 Google 中分离出来（字面上也是——现在这个项目名称就只是“Gears”）并且在开源协议下发布源代码。&lt;/p&gt;
&lt;p&gt;第一个发行版将只关注于 HTML5 里面提议的新功能中他们认为最重要的功能：&lt;a href=&quot;http://www.techcrunch.com/2008/05/29/the-next-gen-web-browser-storage-support/&quot; target=&quot;_blank&quot;&gt;基于客户端的结构化数据和对象存储&lt;/a&gt;。由于选择了首先实现客户端存储，所以下一年里 Gears 会被构架成一个离线应用程序解决方案，由于其他的竞争者好像都没有注意到这个这么巨大目标，所以如果他们不是有意而为之，那么肯定会发展的很好。Google 本来有可能开发他们自己的浏览器，某些博客里的推测和谣言也都指出了这一点，但是浏览器市场竞争激烈，却平淡乏味，而且通常会失败。另外，即使他们开发了自己的新浏览器，他们还要驱使用户接受这个新浏览器，在决定性的市场聚集起来之前只能等待，就是这样，市场上还会有 70% 或者 80% 甚至 90% 的人不使用 Google 的浏览器，却想使用 Google 的程序。&lt;/p&gt;
&lt;p&gt;这种情况下，可选的捷径就是跳过浏览器直接在上面增加一层——Google 自己的 web 层。所有常用浏览器都提供了让开发者扩展功能的机制，这样一来，Google 要做的就是对每个浏览器开发对应的插件。这能让新的 web API 能够适应所有的桌面而不需要用户去适应，最重要的，这比起进入浏览器市场来说见效快而且痛苦少。现在可以让浏览器来做所有无聊的事情：渲染 HTML、显示界面、用户选项等等，与此同时 Google 却在改变现状，埋头向前冲。&lt;/p&gt;
&lt;p&gt;现在 Gears 支持大量完整的新功能，有一些新功能是和微软、Adobe 他们的下一代 web API 相同的，而其他的则是 Google 自己创造出来的。现在函数调用已经&lt;a href=&quot;http://code.google.com/p/gears/w/list&quot; target=&quot;_blank&quot;&gt;对开发者开放&lt;/a&gt;了，包括后台处理（不会再有沙漏出现）、客户端图像处理、位置感知、更好的文件上传功能，还有浏览器内本地数据库。&lt;/p&gt;
&lt;p&gt;要让新 API 和开发平台的应用被采用需要两方面的支持，一方面是用户的支持，因为这需要用户安装新的插件；另一方面是开发者的支持，使用 Gears 不会让开发变得更容易，这是因为这和开发其他的使用基于浏览器的 Javascript 的程序没有区别，Gears 只是给开发者提供了一系列更多的可以在浏览器内实现的功能而已。Javascript 和 web 开发者不需要学习任何新知识，用户也要做的也只是安装一个插件（与浏览器绑定的交易肯定会发生，所以这一步都可以忽略了）。Flash 花了 5 到 6 年才足够普及，能够让开发者有信心专注于使用 Flash 开发，不过有了 Google 的支持，Gears 可能只需要用一半甚至更小的时间就能做到。&lt;/p&gt;
&lt;p&gt;在这场竞赛中，Google 没有任何损失反而赢得盆满钵丰，Google 一下子就启动了这个新 web API 的基于标准且开源的替代方案。与其他的竞争对手不一样，Google 没有兴趣控制这个平台或者直接用来盈利。相反他们却在试图维持现状：大部分程序使用浏览器里的 Javascript 开发，如果有更多需求那就使用 Flash 或者类似的技术。&lt;/p&gt;
&lt;p&gt;上一次平台大战结束了很久了，但是每次你都能看到类似的技术经验：大公司失败，小公司成功。给这个平衡增加点开源的砝码，结果还是没有一个单独的公司能够占优势。有这么多大公司的加入，而且如此的利益攸关，我们肯定要亲眼见证一场漫长的持久战。只有时间能够告诉我们 Google 的做法能不能带领 web 向前发展。&lt;/p&gt;
&lt;p&gt;&lt;i&gt;本文是 Nik Cubrilovic 写的下一代 web 系列中的一篇，&lt;a href=&quot;http://blog.nulltao.net/plugin/tag/nextgenweb&quot;&gt;在这阅读其他同系列文章&lt;/a&gt;。&lt;/i&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 16 Jun 2008 11:06:36 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/88-guid.html</guid>
    <category>nextgenweb</category>
<category>techcrunch</category>
<category>translation</category>
<category>trashcan</category>

</item>
<item>
    <title>下一代 web：浏览器存储支持</title>
    <link>http://blog.nulltao.net/archives/86-web.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/86-web.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=86</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=86</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;原文：&lt;a href=&quot;http://www.techcrunch.com/2008/05/29/the-next-gen-web-browser-storage-support/&quot; target=&quot;_blank&quot;&gt;The Next-Gen Web: Browser Storage Support&lt;/a&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img width=&quot;244&quot; height=&quot;158&quot; border=&quot;0&quot; src=&quot;http://www.techcrunch.com/wp-content/nextgenweb2.jpg&quot; alt=&quot;lame_logo&quot; style=&quot;border-width: 0px; float: left;&quot;/&gt; 下一代的 web 已经开始上路了，就在这个星期，&lt;a href=&quot;http://www.techcrunch.com/2008/05/28/myspace-shows-facebook-how-its-done-google-gears-to-power-messaging/&quot; target=&quot;_blank&quot;&gt;MySpace 集成了 Google Gears&lt;/a&gt;，雅虎发布了&lt;a href=&quot;http://www.techcrunch.com/2008/05/28/yahoo-unveils-webtop-plugin-browserplus-before-its-ready/&quot; target=&quot;_blank&quot;&gt;新的 BrowserPlus&lt;/a&gt;，Google 的浏览器版&lt;a href=&quot;http://www.techcrunch.com/2008/05/28/google-earths-3d-goodness-comes-to-the-browser/&quot; target=&quot;_blank&quot;&gt;三维地球&lt;/a&gt;也上线了。类似 &lt;a href=&quot;http://www.adobe.com/products/air/&quot; target=&quot;_blank&quot;&gt;AIR&lt;/a&gt;、&lt;a href=&quot;http://www.silverlight.net&quot; target=&quot;_blank&quot;&gt;Silverlight&lt;/a&gt;、&lt;a href=&quot;http://www.techcrunch.com/java.sun.com/javafx/&quot; target=&quot;_blank&quot;&gt;JavaFX&lt;/a&gt;、&lt;a href=&quot;http://gears.google.com&quot; target=&quot;_blank&quot;&gt;Gears&lt;/a&gt;、&lt;a href=&quot;http://www.mozilla.org/projects/xul/&quot; target=&quot;_blank&quot;&gt;XUL&lt;/a&gt;、&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/2005-09-01/&quot; target=&quot;_blank&quot;&gt;Web Applications 1.0&lt;/a&gt; (DOM5, HTML5 等) 这样的技术和格式让开发者能够超过 AJAX 加速冲向下一代的，有着更好的性能、更多的功能，而且和桌面集成的更加紧密的 web 程序。&lt;/p&gt;
	&lt;p&gt;现在，因为各个公司都急于展示他们自己的下一代 web 的样子，导致开发者和用户都被前所未有的超多 web 技术所压迫；“DLL 地狱”也被“插件地域”所取代。但是在 web 上，这样过多的选择会导致用户和开发者的成本增加。第一次 web 格式大战已经过去十多年了，那个时候微软、网景、苹果、美国在线还有其他公司都在浏览器标准、脚本语言、web 服务等方面成立了不同的基金会。这次大战的影响一直持续到现在，例如 Javascript 来发展需要依赖&lt;a href=&quot;http://www.dojotoolkit.org/&quot; target=&quot;_blank&quot;&gt;整套&lt;/a&gt;的&lt;a href=&quot;http://developer.yahoo.com/yui/&quot; target=&quot;_blank&quot;&gt;代码库&lt;/a&gt;来开发跨浏览器代码，CSS 开发者需要&lt;a href=&quot;http://www.webdevout.net/css-hacks&quot; target=&quot;_blank&quot;&gt;一系列 hack&lt;/a&gt; 才能让他们的站点能够在不同的浏览器中看起来都一样。&lt;/p&gt;
	&lt;p&gt;现在新一代的富 web 程序技术还都在开发阶段，所以还有机会采用基于标准的态度，来避免重蹈覆辙。幸亏有了过去十多年的教训，现在连微软这样的公司都在以更加开放的姿态来接纳开放标准、数据迁移还有跨平台支持。不管是用户还是开发者，对开放标准的广泛支持都能简化他们用到的技术，但是明显的，并不是所有当前发布的新技术都能支持开放标准。&lt;/p&gt;
&lt;p&gt;在 Techcrunch 这一系列帖子里，我们来看看这些组成新一代 web 的各种元素，并且评估可用的选项，当前支持的标准以及对标准的采用情况。由于 MySpace 刚刚宣布他们在程序里面使用了 Google Gears，那么我们的第一篇就来评估基于浏览器的本地缓存。&lt;/p&gt;
&lt;p&gt;&lt;big&gt;&lt;strong&gt;基于浏览器的本地存储&lt;/strong&gt;&lt;/big&gt;&lt;/p&gt;
&lt;p&gt;随着基于 web 的应用程序逐渐流行，就有了希望能够离线运行这些程序的需求。第一个不需要任何插件或者独立程序的解决方案是那些靠缓存 HTTP 头信息来在浏览器缓存里存储信息的方法。类似 &lt;a href=&quot;http://www.sitepen.com/blog/2007/01/23/the-dojo-offline-api/&quot; target=&quot;_blank&quot;&gt;Dojo 对离线 web 应用的支持&lt;/a&gt;这样的 Javascript 库使用的就是这样的原理，但是这样的程序应用范围非常狭窄，因为没有一个好的办法在浏览器里存储结构化的数据。（Dojo 现在引用了很多&lt;a href=&quot;http://dojotoolkit.org/offline&quot; target=&quot;_blank&quot;&gt;包括 Gears 在内的其他的存储引擎&lt;/a&gt;——提示：&lt;a href=&quot;http://www.dylanschiemann.com/&quot; target=&quot;_blank&quot;&gt;Dylan&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;在 2007 年 5 月，Google 发布了&lt;a href=&quot;http://gears.google.com&quot; target=&quot;_blank&quot;&gt;Google Gears&lt;/a&gt;，一个浏览器插件，它允许 web 程序把数据同步到本地存储器，然后可以离线使用这些 web 程序。在 Gears 发布会上，Google Reader 被重写以支持 Gears，Gears 的突出的重点是离线访问应用程序。但是不被所知的是，Gears 不仅仅能够用来离线访问，它还提供这三大功能：
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;缓存资源（HTML 页面、图片等）&lt;/li&gt;
&lt;li&gt;在数据库中存储结构化数据&lt;/li&gt;
&lt;li&gt;异步后台工作线程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在这部分我们关注的是本地对象和结构化数据存储。Gears 通过 Javascript API 来提供相应的功能，这些 API 可以被任何 web 程序访问到。&lt;a href=&quot;http://www.sqlite.org&quot; target=&quot;_blank&quot;&gt;Sqlite&lt;/a&gt;，一个轻量级 RDBMS，提供了结构化存储的支持。由于使用了本地数据库，开发者不仅可以执行查询、插入新纪录这样的操作，还能执行更复杂的 SQL 操作，例如连接多表查询等。尽管你可以有多个使用 Gears 的程序，但是每个程序都要运行在一个基于域名的安全模型的沙盒环境里（类似 cookie 和 AJAX 请求）。虽然 Sqlite 已经&lt;a href=&quot;http://developer.mozilla.org/en/docs/Storage&quot; target=&quot;_blank&quot;&gt;嵌入 Firefox 2.0 以后的版本&lt;/a&gt;，但是它的 API 只能够被 Firefox 核心组件或者附加模块访问到。Gears 插件弥补了这个缺陷，让客户端脚本环境也能够访问到这些 API。&lt;/p&gt;
&lt;p&gt;在 Gears 发布前，&lt;a href=&quot;http://www.whatwg.org/&quot; target=&quot;_blank&quot;&gt;万维网超文本应用程序技术工作组&lt;/a&gt; (WHATWG) 已经着手制定 Web 程序规范 1.0 草案，这个草案把结构化数据存储包括到了 HTML5 里。该草案当前版本包含了对访问&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#structured&quot; target=&quot;_blank&quot;&gt;数据库对象&lt;/a&gt;和查询本地数据存储的定义。实现的细节虽然交给了各个公司去完成，不过规范里面已经详细说明了 API 的细节。Firefox 将会在 &lt;a href=&quot;http://developer.mozilla.org/en/docs/Firefox_3_for_developers&quot; target=&quot;_blank&quot;&gt;3.0 版&lt;/a&gt;里实现一部分和 WHATW 规范一样的存储 API，不过这个版本现在只有预览版可用。WHATWG 规范里的关键部分有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#offline&quot; target=&quot;_blank&quot;&gt;程序缓存&lt;/a&gt; &lt;/em&gt;——在本地浏览器缓存里存储对象（包含校验）。&lt;/li&gt;
&lt;li&gt;navigator.onLine——测试浏览器是否在线（使用缓存，如果需要则加上本地数据存储）。&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#storage&quot; target=&quot;_blank&quot;&gt;存储&lt;/a&gt;&lt;/em&gt;界面和事件——用来通过 &lt;u&gt;sessionStorage&lt;/u&gt; DOM 属性存储“名称／值”对。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#sql&quot; target=&quot;_blank&quot;&gt;数据库&lt;/a&gt;&lt;/em&gt;界面——用来连接本地数据库。支持 SQL语法（或者其子集，取决于使用的服务器）、版本控制和错误回调事件。&lt;/li&gt;
&lt;li&gt;线程和回调——这样多个请求就能够异步发送给本地数据存储。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;调用本地存储、缓存和离线访问相对来说很简单。程序首先检查是否支持相应的函数，然后通过在后台同步用户数据进程来设置本地缓存。当一个线程在运行的时候，不管是上传还是下载，你可以查询进程状态并且给用户一个反馈（例如一个进度条）。一旦数据本地化，由于是在本地机器上运行数据库，开发者就能&lt;em&gt;大幅度的&lt;/em&gt;提高查询性能。当下很多 web 程序仅仅把浏览器用作展示层，例如，电子表格软件就是做 &lt;em&gt;=1+1&lt;/em&gt; 这样简单的计算也要进行一次到服务器再返回的请求。通过使用本地数据存储和客户端代码，开发者可以减少到处理和存储到客户端的负荷，同时还能提供给用户更加平滑、类似桌面程序的体验。&lt;/p&gt;
&lt;p&gt;&lt;big&gt;&lt;strong&gt;当前和将来的支持情况&lt;/strong&gt;&lt;/big&gt;&lt;/p&gt;
&lt;p&gt;现在的问题是大部分 WHATW 规范都是在 Gears 发布后才写的，导致 Gears 使用的数据库和本地服务器对象和 WHATW 规范不兼容——至少当下是这样的。好消息是 Google 已经发现了这个问题，&lt;a href=&quot;http://gearsblog.blogspot.com/2008/04/gears-and-standards.html&quot; target=&quot;_blank&quot;&gt;完全支持&lt;/a&gt; WHATWG HTML5 规范中的存储部分，因此，对于那些运行在安装了 Gears 的 Firefox 3 中的程序的开发者来说，他们可以选择使用 Firefox 原生的还是 Google 实现的存储。Google 还说他们很可能会提供额外的功能，以激励开发者关注那些 Gears 超越 HTML5 的实现（例如桌面快捷方式等）。&lt;/p&gt;
&lt;p&gt;其他的本地数据存储可选方案，例如 Flash 本地存储，和 WHATW 规范完全不兼容。&lt;a href=&quot;http://webkit.org/blog/126/webkit-does-html5-client-side-database-storage/&quot; target=&quot;_blank&quot;&gt;WebKit 的开发人员很快声明&lt;/a&gt;他们也开始实现 HTML5 规范中的存储部分。而且在每晚构建的代码里已经可用了，因此很快我们就能看到 Konquror 和 Safari 对本地存储的支持。Opera 也声明了类似的计划，而且当然他实现了 HTML5 和 web 表单后他们会领先于所有人。雅虎 BrowserPlus 昨天才发布，所以现在还不明确他们他们的本地存储支持和工作组发布的规范是否兼容。&lt;/p&gt;
&lt;p&gt;本地存储是新一代的 web API 中重要的新功能，开发者不仅有跨浏览器的一致支持，还可以选择使用 Google Gears（已经可用）还是 Yahoo! BrowserPlus（取决于它如果工作）。还有一个浏览器厂商我们到现在一直没有谈到，那就是微软。微软发布了 IE8 的一个早期预览版，而且预告了大量的新特性，其中很多都是基于开放标准的，例如更好的 CSS 和 Javascript 支持（内涵一个更加标准化的对象模型）。最大问题是，IE8 在本地存储方面会不会遵循和其他浏览器厂商一致规范。IE 开发小组声称 IE8 &lt;a href=&quot;http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/DevelopersNew.htm#ajax&quot; target=&quot;_blank&quot;&gt;将会支持 DOM 存储&lt;/a&gt;，但是这只是全部本次存储规范的一部分（即前面提到的 &lt;em&gt;Storage &lt;/em&gt; 对象）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;big&gt;当前和将来的支持情况&lt;/big&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;table width=&quot;100%&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; border=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot; width=&quot;20%&quot;&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot; width=&quot;16%&quot; align=&quot;center&quot;&gt;&lt;strong&gt;Gears&lt;/strong&gt;&lt;/td&gt;
&lt;td width=&quot;16%&quot;  align=&quot;center&quot;&gt;&lt;strong&gt;BrowserPlus&lt;/strong&gt;&lt;/td&gt;
&lt;td width=&quot;16%&quot;  align=&quot;center&quot;&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;/td&gt;
&lt;td width=&quot;16%&quot;  align=&quot;center&quot;&gt;&lt;strong&gt;IE8&lt;/strong&gt;&lt;/td&gt;
&lt;td width=&quot;16%&quot;  align=&quot;center&quot;&gt;&lt;strong&gt;Webkit&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;程序缓存&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;很快&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;侦测在线与否&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;本地服务器&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;102&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/no1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;存储&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;75&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;103&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;数据库&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;75&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/no1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;线程&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;75&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;105&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/no1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;80&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;left&quot;&gt;&lt;strong&gt;SQL&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;75&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;106&quot; valign=&quot;top&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/unknown.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/no1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td align=&quot;middle&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;http://www.techcrunch.com/wp-content/yes1.jpg&quot;/&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;small&gt;注：一旦得知 BrowserPlus 的细节，我们就会完成这个表格。Google 保证 Gears 能够适应标准。IE8 宣称不完全的支持。WebKit 的每晚构建里面大部分功能都可用了。Flash 和 Silverlight 支持某种形式的本次存储但是不是 HTML5 标准 API。&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;一个类似本地浏览器存储这样的新技术被如此广泛的提倡和支持，而且大部分都是基于一个规范，实在是一件罕见的事情。虽然微软还没有宣称完全支持，但是毫无疑问的，他们会朝向正确的方向。Google Gears 和 Firefox 3 的实现都遵循着 HTML5 的工作组规范也是很鼓舞人心的。虽然短时间内这些新版本的浏览器不可能被广泛的使用，但是 Google Gears 已经可用了，而且，因为所有的厂商都瞄准了同样的 API，开发者现在就可以安心的锁定 Gears 存储 API 然后开工——者在不久以前还是不可能的事情。&lt;/p&gt;
&lt;p&gt;有了本地浏览器存储和缓存，开放标准到现在为止都是赢家。而其他的替代解决方案很可能会半途而废，或者改变以实现同样的 API。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 07 Jun 2008 02:40:17 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/86-guid.html</guid>
    <category>nextgenweb</category>
<category>techcrunch</category>
<category>translation</category>

</item>
<item>
    <title>PHP 基准测试</title>
    <link>http://blog.nulltao.net/archives/85-PHP.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/85-PHP.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=85</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=85</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;原文：&lt;a href=&quot;http://www.webappers.com/2008/06/05/the-php-benchmark/&quot; target=&quot;_blank&quot;&gt;The PHP Benchmark | Web Resources | WebAppers&lt;/a&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;创建 &lt;a target=&quot;_blank&quot; title=&quot;The PHP Benchmark&quot; href=&quot;http://www.phpbench.com/&quot;&gt;PHPBench&lt;/a&gt; 的目的是让你看到每一个 PHP 代码段的运行速度不都是一样的。看到 PHPBench 生成的结果，你很可能会大吃一惊。这个网站还有一个目的就是让你自己去发现一些规律，然后在你自己的服务器环境里，使用示例代码重新运行这些测试来验证你的发现。而且你还可以看到一些 PHPBench 测到的有趣的结论：&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a target=&quot;_blank&quot; title=&quot;The PHP Benchmark&quot; href=&quot;http://www.phpbench.com/&quot;&gt;&lt;img src=&quot;http://www.webappers.com/img/2008/06/phpbench.png&quot; alt=&quot;PHP Benchmarking&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;很奇怪的结果表明，如果你执行&lt;em&gt;&lt;strong&gt;sizeof()，那么是否预先计算循环的次数基本上没有什么区别&lt;/strong&gt;&lt;/em&gt;。&lt;li&gt;
&lt;li&gt; 事实上，each 和 print 执行的功能完全一样，因此都适用于同样的代码段。有一小点需要注意的就是，当你&lt;em&gt;&lt;strong&gt;使用逗号分隔输出列表并且使用 echo 输出，则会运行的稍微快一丁点&lt;/strong&gt;&lt;/em&gt;。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;while 循环在 90% 的情况下确实能够快一点点。&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;blockquote&gt;&lt;p&gt;需求: -&lt;br /&gt;
演示: &lt;a target=&quot;_blank&quot; title=&quot;Demo&quot; href=&quot;http://www.phpbench.com/&quot;&gt;http://www.phpbench.com/&lt;/a&gt;&lt;br /&gt;
协议: 自由协议&lt;/p&gt;&lt;/blockquote&gt; 
    </content:encoded>

    <pubDate>Thu, 05 Jun 2008 23:52:03 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/85-guid.html</guid>
    <category>benchmark</category>
<category>php</category>
<category>translation</category>

</item>
<item>
    <title>胡言乱语之男人女人</title>
    <link>http://blog.nulltao.net/archives/74-unknown.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/74-unknown.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=74</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=74</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;p&gt;这年头，男人除了生孩子什么都得学会，女人还天天腻腻歪歪的不想生孩子——最近几对同学结婚有感。&lt;/p&gt;
&lt;p&gt;--------------------结婚多可怕的分割线--------------------&lt;/p&gt;
&lt;p&gt;去年过年时，一异性死党跟偶讨教感情问题，偶立下三个关于她有了男友之后的预言（注：其实该女当时已经有了男友，就是不说），年中时电话偶，第一个预言已经实现了。&lt;/p&gt;
&lt;p&gt;该预言是：他二位定会在一个美好的下午，在温馨的小家里，沐浴着首都的夕阳，然后用各种高级的厨具，搭配着精致的调料，一起做出一桌幸福的晚餐——然后全都到掉，出门下馆子去。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 27 Feb 2008 16:20:15 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/74-guid.html</guid>
    <category>saying</category>
<category>translation</category>
<category>trashcan</category>

</item>
<item>
    <title>PHP Security / Sessions / Session Fixation</title>
    <link>http://blog.nulltao.net/archives/50-PHP-Security-Sessions-Session-Fixation.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/50-PHP-Security-Sessions-Session-Fixation.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=50</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=50</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;h3&gt;Session Fixation&lt;/h3&gt;
&lt;h3&gt;会话固定攻击&lt;/h3&gt;
&lt;p&gt;
	Session security is a sophisticated topic, and it&#039;s no surprise that sessions are a
	frequent target of attack. Most session attacks involve impersonation, where the
	attacker attempts to gain access to another user&#039;s session.
&lt;/p&gt;
&lt;p&gt;
	会话安全是一个老生常谈的话题了，会话作为一个常见的攻击目标一点也不稀奇。
	绝大多数的会话攻击都用的是会话伪装，攻击者要试图用这种方法访问另外一个用户的会话。
&lt;/p&gt;
&lt;p&gt;
	The most crucial piece of information for an attacker is the session identifier,
	because this is required for any impersonation attack. There are three common
	methods used to obtain a valid session identifier:
&lt;/p&gt;
&lt;p&gt;
	对于攻击者来说，最重要的信息就是会话 ID，因为这对任何伪装攻击都是非常重要的。
	要想得到一个合法的会话 ID，有三种常见的办法：
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Prediction&lt;/li&gt;
	&lt;li&gt;Capture&lt;/li&gt;
	&lt;li&gt;Fixation&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
	&lt;li&gt;预测&lt;/li&gt;
	&lt;li&gt;捕获&lt;/li&gt;
	&lt;li&gt;固定&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	Prediction refers to guessing a valid session identifier. With PHP&#039;s native session
	mechanism, the session identifier is extremely random, and this is unlikely to be
	the weakest point in your implementation.
&lt;/p&gt;
&lt;p&gt;
	预测就是猜想一个合法会话 ID。根据 PHP 原生的会话机制，会话 ID 非常的随机，
	所以不太可能是你程序的最薄弱的环节。
&lt;/p&gt;
&lt;p&gt;
	Capturing a valid session identifier is the most common type of session attack,
	and there are numerous approaches. Because session identifiers are typically
	propagated in cookies or as GET variables, the different approaches focus on
	attacking these methods of transfer. While there have been a few browser
	vulnerabilities regarding cookies, these have mostly been Internet Explorer, and
	cookies are slightly less exposed than GET variables. Thus, for those users who
	enable cookies, you can provide them with a more secure mechanism.
&lt;/p&gt;
&lt;p&gt;
    捕获一个合法的会话 ID 是会话攻击中最常用的方法，而且有很多不同的方式。
    因为会话 ID 通常都是通过 cookie 或者 GET 变量传递，
    所以各种攻击方法的区别之处就在于攻击哪种传输 ID 的方法。
    虽然有几个关于处理 cookie 的浏览器漏洞，IE 的漏洞最多，
    而且比起 GET 变量来，cookie 不太可能被暴露。
    所以，对于那些启用了 cookie 的用户，你可以给他们提供更安全的会话机制。
&lt;/p&gt;
&lt;p&gt;
	Fixation is the simplest method of obtaining a valid session identifier. While it&#039;s
	not very difficult to defend against, if your session mechanism consists of nothing
	more than &lt;code&gt;session_start()&lt;/code&gt;, you are vulnerable.
&lt;/p&gt;
&lt;p&gt;
	会话固定是得到一个合法的会话 ID 的最简单的方法。
	虽然防御这种攻击不是很难，但是如果你的会话机制只使用了 &lt;code&gt;session_start()&lt;/code&gt; 的话，
	你的系统非常容易受到攻击。
&lt;/p&gt;
&lt;p&gt;
	In order to demonstrate session fixation, I will use the following script,
	&lt;code&gt;session.php&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;我用下面这个 &lt;code&gt;session.php&lt;/code&gt; 脚本来示范一下会话固定：&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;a href=&quot;http://www.php.net/session_start&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;session_start&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;!&lt;a href=&quot;http://www.php.net/isset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;visits&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;visits&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #cc66cc;&quot;&gt;1&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;visits&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;++;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;visits&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	Upon first visiting the page, you should see &lt;code&gt;1&lt;/code&gt; output to the screen. On each
	subsequent visit, this should increment to reflect how many times you have
	visited the page.
&lt;/p&gt;
&lt;p&gt;
	在你第一次访问这个页面的时候，你应该能够看到屏幕上输出的 &lt;code&gt;1&lt;/code&gt;。
	接下来的每一次访问，这个输出结果应该每次加一，以反映你访问了这个页面多少次。
&lt;/p&gt;
&lt;p&gt;
	To demonstrate session fixation, first make sure that you do not have an existing
	session identifier (perhaps delete your cookies), then visit this page with
	&lt;code&gt;?PHPSESSID=1234&lt;/code&gt; appended to the URL. Next, with a completely different
	browser (or even a completely different computer), visit the same URL again with
	&lt;code&gt;?PHPSESSID=1234&lt;/code&gt; appended. You will notice that you do not see &lt;code&gt;1&lt;/code&gt; output on
	your first visit, but rather it continues the session you previously initiated.
&lt;/p&gt;
&lt;p&gt;
	为了演示会话固定攻击，首先要确保你现在没有任何已存在的会话 ID（可以试着删除 cookie），
	然后访问这个页面，访问的时候在 URL 后面附加上 &lt;code&gt;?PHPSESSID=1234&lt;/code&gt;。
	然后，用一个完全不同的浏览器（最好换一台计算机），同样在 URL 后面附加上 &lt;code&gt;?PHPSESSID=1234&lt;/code&gt;
	再次访问这个页面。你会发现你在首次访问的时候看见的输出不是 &lt;code&gt;1&lt;/code&gt;，
	而是继续刚才初始化的那个会话。
&lt;/p&gt;
&lt;p&gt;
	Why can this be problematic? Most session fixation attacks simply use a link or a
	protocol-level redirect to send a user to a remote site with a session identifier
	appended to the URL. The user likely won&#039;t notice, since the site will behave
	exactly the same. Because the attacker chose the session identifier, it is already
	known, and this can be used to launch impersonation attacks such as session
	hijacking.
&lt;/p&gt;
&lt;p&gt;
	为什么会话固定会成问题？大多数会话固定攻击者都是简单的使用一个链接，
	或者一个协议层的重定向来给远程站点发送用户信息，也是通过在 URL 后面附加会话 ID 的方法。
	因为这个站点的行为完全的一样，所以用户不太可能注意到。
	又因为会话 ID 是攻击者选定的，这是已知的，所以这可以用来发动更加类似会话劫持这样的攻击。
&lt;/p&gt;
&lt;p&gt;
	A simplistic attack such as this is quite easy to prevent. If there isn&#039;t an active
	session associated with a session identifier that the user is presenting, then
	regenerate it just to be sure:
&lt;/p&gt;
&lt;p&gt;
	我们可以很容易的防范这种非常简单的攻击。如果用户提供了一个会话 ID，
	但是没有任何活动的会话与之相关联，那么就重新声称一个 ID 以确保保险。
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;a href=&quot;http://www.php.net/session_start&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;session_start&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;!&lt;a href=&quot;http://www.php.net/isset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;initiated&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;a href=&quot;http://www.php.net/session_regenerate_id&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;session_regenerate_id&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #0000ff;&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;initiated&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;true&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	The problem with such a simplistic defense is that an attacker can simply
	initialize a session for a particular session identifier, and then use that identifier to
	launch the attack.
&lt;/p&gt;
&lt;p&gt;
	这种简单的防御有一个问题，就是攻击者很容易就能初始化一个有着特定 ID 的会话，
	然后用这个 ID 来发动攻击。
&lt;/p&gt;
&lt;p&gt;
	To protect against this type of attack, first consider that session hijacking is only
	really useful after the user has logged in or otherwise obtained a heightened level
	of privilege. So, if we modify the approach to regenerate the session identifier
	whenever there is any change in privilege level (for example, after verifying a
	username and password), we will have practically eliminated the risk of a
	successful session fixation attack.
&lt;/p&gt;
&lt;p&gt;
	要防御这种类型的攻击首先要考虑的是会话劫持只有在用户登录了，或者得到了更高权限后才能发挥作用。
	所以，如果我们在权限状态发生任何变化（例如，确认和用户名和密码）后都重新生成会话 ID，
	这样就能够消除因为成功的会话固定攻击所带来的风险。
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 01 Jul 2007 22:44:27 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/50-guid.html</guid>
    <category>php</category>
<category>security</category>
<category>translation</category>

</item>
<item>
    <title>PHP Security / Databases and SQL / SQL Injection</title>
    <link>http://blog.nulltao.net/archives/45-PHP-Security-Databases-and-SQL-SQL-Injection.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/45-PHP-Security-Databases-and-SQL-SQL-Injection.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=45</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=45</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;h3&gt;SQL Injection&lt;/h3&gt;
&lt;h3&gt;SQL 注入&lt;/h3&gt;
&lt;p&gt;
	SQL injection attacks are extremely simple to defend against, but many
	applications are still vulnerable. Consider the following SQL statement:
&lt;/p&gt;
&lt;p&gt;
	SQL 注入攻击很容易就能防范，但是很多程序在这方面还是很脆弱的。
	看下面的 SQL 语句：
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$sql&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;INSERT&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160;INTO users (reg_username,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;reg_password,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;reg_email)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160;VALUES (&#039;{$_POST[&#039;reg_username&#039;]}&#039;,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&#039;$reg_password&#039;,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&#039;{$_POST[&#039;reg_email&#039;]}&#039;)&amp;quot;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	This query is constructed with &lt;code&gt;$_POST&lt;/code&gt;, which should immediately look
	suspicious.
&lt;/p&gt;
&lt;p&gt;这个查询使用 &lt;code&gt;$_POST&lt;/code&gt; 进行构造，这样一眼就能够看出问题。&lt;/p&gt;
&lt;p&gt;
	Assume that this query is creating a new account. The user provides a desired
	username and an email address. The registration application generates a
	temporary password and emails it to the user to verify the email address.
	Imagine that the user enters the following as a username:
&lt;/p&gt;
&lt;p&gt;
	假设这个查询时用来创建新帐号用的。用户指定他们想要用户名和 email 地址。
	然后注册程序生成一个临时密码并且发送给用户以验证 email 地址。
	假设用户输入了一个这样的用户名；
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bad_guy&#039;, &#039;mypass&#039;, &#039;&#039;), (&#039;good_guy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	This certainly doesn&#039;t look like a valid username, but with no data filtering in
	place, the application can&#039;t tell. If a valid email address is given
	(&lt;code&gt;shiflett@php.net&lt;/code&gt;, for example), and &lt;code&gt;1234&lt;/code&gt; is what the application generates
	for the password, the SQL statement becomes the following:
&lt;/p&gt;
&lt;p&gt;
	这个用户名看起来肯定不是一个合法的用户名，但是如果没有适当的数据过滤，
	程序是区分不出来的。如果给定了一个合法的 email 地址（例如 &lt;code&gt;shiflett@php.net&lt;/code&gt;），
	程序生成的密码是 &lt;code&gt;1234&lt;/code&gt;，那么这个 SQL 语句就变成下面这个样子：
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$sql&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;INSERT&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160;INTO users (reg_username,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;reg_password,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;reg_email)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160;VALUES (&#039; bad_guy&#039;, &#039;mypass&#039;, &#039;&#039;),&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; (&#039;good_guy&#039;,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&#039;1234&#039;,&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&#039;shiflett@php.net&#039;)&amp;quot;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	Rather than the intended action of creating a single account (&lt;code&gt;good_guy&lt;/code&gt;) with a
	valid email address, the application has been tricked into creating two accounts,
	and the user supplied every detail of the &lt;code&gt;bad_guy&lt;/code&gt; account.
&lt;/p&gt;
&lt;p&gt;
	本来预期的动作是创建一个有合法 email 地址的单一帐号（&lt;code&gt;good_guy&lt;/code&gt;），
	但是程序实际上被欺骗而创建了两个帐号，而且用户还指定了 &lt;code&gt;bad_guy&lt;/code&gt; 帐号的所有信息。
&lt;/p&gt;
&lt;p&gt;
	While this particular example might not seem so harmful, it should be clear that
	worse things could happen once an attacker can make modifications to your SQL
	statements.
&lt;/p&gt;
&lt;p&gt;
	虽然这个特定的例子看起来没有那么大的危害，但是这说明了一旦攻击者能够修改你的 SQL 语句，
	不定发生什么糟糕的事情呢。
&lt;/p&gt;
&lt;p&gt;
	For example, 	 on the database you are using, it might be possible to
	send multiple queries to the database server in a single call. Thus, a user can
	potentially terminate the existing query with a semicolon and follow this with a
	query of the user&#039;s choosing.
&lt;/p&gt;
&lt;p&gt;
	例如，根据你用的数据库，很可能允许在一次调用中发送多个查询请求。
	这样，用户就可能能够用一个分号终止当前的查询，然后紧跟着加入用户所选择的查询。
&lt;/p&gt;
&lt;p&gt;
	MySQL, until recently, does not allow multiple queries, so this particular risk is
	mitigated. Newer versions of MySQL allow multiple queries, but the
	corresponding PHP extension (&lt;code&gt;ext/mysqli&lt;/code&gt;) requires that you use a separate
	function if you want to send multiple queries (&lt;code&gt;mysqli_multi_query()&lt;/code&gt; instead
	of &lt;code&gt;mysqli_query()&lt;/code&gt;). Only allowing a single query is safer, because it limits
	what an attacker can potentially do.
&lt;/p&gt;
&lt;p&gt;
	到目前为止，MySQL 还不允许多重查询，所以这个特定的风险倒是不大。
	MySQL 的新版支持多重查询，不过对应的 PHP 扩展（&lt;code&gt;ext/mysqli&lt;/code&gt;）
	要求你在希望进行多重查询的时候使用单独的函数（用 &lt;code&gt;mysqli_multi_query()&lt;/code&gt; 替代 &lt;code&gt;mysqli_query()&lt;/code&gt;）。
	因为单一查询能够限制攻击者可能做的事情，所以使用单一查询更加安全。
&lt;/p&gt;
&lt;p&gt;Protecting against SQL injection is easy:&lt;/p&gt;
&lt;p&gt;防范 SQL 注入还是很简单的：&lt;/p&gt;
&lt;ul type=&quot;square&quot;&gt;
	&lt;li&gt;
		&lt;h4&gt;Filter your data.&lt;/h4&gt;
		&lt;p&gt;
			This cannot be overstressed. With good data filtering in place, most
			security concerns are mitigated, and some are practically eliminated.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;过滤数据。&lt;/h4&gt;
		&lt;p&gt;
			这是绝对不能被越过的。如果在适当的地方有很好的数据过滤，
			大多数安全隐患都能够减轻，甚至差不多都能够消除。
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;Quote your data.&lt;/h4&gt;
		&lt;p&gt;
			If your database allows it (MySQL does), put single quotes around all
			values in your SQL statements, regardless of the data type.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;给数据加引号。&lt;/h4&gt;
		&lt;p&gt;
			如果你的数据库支持，在 SQL 语句里给所有的值都加上单引号，不管是什么类型的数据。
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;Escape your data.&lt;/h4&gt;
		&lt;p&gt;
			Sometimes valid data can unintentionally interfere with the format of the
			SQL statement itself. Use &lt;code&gt;mysql_escape_string()&lt;/code&gt; or an escaping
			function native to your particular database. If there isn&#039;t a specific one,
			&lt;code&gt;addslashes()&lt;/code&gt; is a good last resort.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;数据转义。&lt;/h4&gt;
		&lt;p&gt;
			有一些数据，虽然是合法的，但是可能会在无意中和 SQL 语句的格式产生冲突。
			那么就使用 &lt;code&gt;mysql_escape_string()&lt;/code&gt; 函数，或者你的数据库原生的转义函数进行数据转义。
			如果没有特定的转义函数，&lt;code&gt;addslashes()&lt;/code&gt; 是最后手段。
		&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt; 
    </content:encoded>

    <pubDate>Tue, 19 Jun 2007 01:25:38 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/45-guid.html</guid>
    <category>php</category>
<category>security</category>
<category>translation</category>

</item>
<item>
    <title>PHP Security / Databases and SQL / Exposed Access Credentials</title>
    <link>http://blog.nulltao.net/archives/44-PHP-Security-Databases-and-SQL-Exposed-Access-Credentials.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/44-PHP-Security-Databases-and-SQL-Exposed-Access-Credentials.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=44</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=44</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;h3&gt;Exposed Access Credentials&lt;/h3&gt;
&lt;h3&gt;连接信息泄漏&lt;/h3&gt;
&lt;p&gt;
	Most PHP applications interact with a database. This usually involves connecting
	to a database server and using access credentials to authenticate:
&lt;/p&gt;
&lt;p&gt;
	绝大多数的 PHP 程序都要和数据库交互。
	这个交互过程通常都是首先连接到数据数据库，然后通过连接信息认证。
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$host&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;example.org&#039;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$username&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;myuser&#039;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$password&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;mypass&#039;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$db&lt;/span&gt; = &lt;a href=&quot;http://www.php.net/mysql_connect&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;mysql_connect&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$host&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$username&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$password&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	This could be an example of a file called &lt;code&gt;db.inc&lt;/code&gt; that is included whenever a
	connection to the database is needed. This approach is convenient, and it keeps
	the access credentials in a single file.
&lt;/p&gt;
&lt;p&gt;
	这可以作为一个用来演示 &lt;code&gt;db.inc&lt;/code&gt; 文件的例子，你可以在任何需要数据库连接的时候引用这个文件。
	这样就可以把连接信息保存在单一文件里，这倒是挺方便的。
&lt;/p&gt;
&lt;p&gt;
	Potential problems arise when this file is somewhere within document root. This
	is a common approach, because it makes &lt;code&gt;include&lt;/code&gt; and &lt;code&gt;require&lt;/code&gt; statements
	much simpler, but it can lead to situations that expose your access credentials.
&lt;/p&gt;
&lt;p&gt;
	如果你把这个文件放在文档根目录里面的话，潜在的问题就会显现出来。
	这样放是很常见的，因为能够让 &lt;code&gt;include&lt;/code&gt; 和 &lt;code&gt;require&lt;/code&gt; 语句写起来很简单，
	但是这会引起连接信息的泄露。
&lt;/p&gt;
&lt;p&gt;
	Remember that everything within document root has a URL associated with it.
	For example, if document root is &lt;code&gt;/usr/local/apache/htdocs&lt;/code&gt;, then a file
	located at &lt;code&gt;/usr/local/apache/htdocs/inc/db.inc&lt;/code&gt; has a URL such as
	&lt;code&gt;http://example.org/inc/db.inc&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
	请记住，在文档根目录里面的所有文件都有一个对应的 URL。
	例如，如果文档根目录是 &lt;code&gt;/usr/local/apache/htdocs&lt;/code&gt;，
	那么一个位于 &lt;code&gt;/usr/local/apache/htdocs/inc/db.inc&lt;/code&gt; 的文件，
	就对应着一个类似 &lt;code&gt;http://example.org/inc/db.inc&lt;/code&gt; 这样的 URL。
&lt;/p&gt;
&lt;p&gt;
	Combine this with the fact that most Web servers will serve &lt;code&gt;.inc&lt;/code&gt; files as plain
	text, and the risk of exposing your access credentials should be clear. A bigger
	problem is that any source code in these modules can be exposed, but access
	credentials are particularly sensitive.
&lt;/p&gt;
&lt;p&gt;
	大多数 Web 服务器都把 &lt;code&gt;.inc&lt;/code&gt; 文件作为普通文本处理，把这个事实和上面的规则一起考虑，
	由于泄露连接信息所引发的风险就很明了了。
	还有一个更大的问题，就是任何在这些模块里面的源代码都有泄露的可能，
	当然了，连接信息是最为敏感的。
&lt;/p&gt;
&lt;p&gt;
	Of course, one simple solution is to place all modules outside of document root,
	and this is a good practice. Both &lt;code&gt;include&lt;/code&gt; and &lt;code&gt;require&lt;/code&gt; can accept a filesystem
	path, so there&#039;s no need to make modules accessible via URL. It is an
	unnecessary risk.
&lt;/p&gt;
&lt;p&gt;
	当然了，一个简单但是很好的解决方法就是把这些模块都放到文档根目录外面。
	&lt;code&gt;include&lt;/code&gt; 和 &lt;code&gt;require&lt;/code&gt; 语句都能够接受文件系统路径作为参数，
	因此，没有必要让人通过 URL 访问这些模块。这是一个不必要的风险。
&lt;/p&gt;
&lt;p&gt;
	If you have no choice in the placement of your modules, and they must be within
	document root, you can put something like the following in your &lt;code&gt;httpd.conf&lt;/code&gt; file
	(assuming Apache):
&lt;/p&gt;
&lt;p&gt;
	如果你无法选择放置这些模块的地方，而且必须放置到文档根目录里，
	那么你可以在你的 &lt;code&gt;httpd.conf&lt;/code&gt; 文件（假设你使用的是 Apache 服务器）里增加如下语句：
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;lt;Files ~ &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&lt;span style=&quot;color: #000099; font-weight: bold;&quot;&gt;\.&lt;/span&gt;inc$&amp;quot;&lt;/span&gt;&amp;gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Order allow, deny&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Deny from all&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;lt;/Files&amp;gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	It is not a good idea to have your modules processed by the PHP engine. This
	includes renaming your modules with a &lt;code&gt;.php&lt;/code&gt; extension as well as using
	&lt;code&gt;AddType&lt;/code&gt; to have &lt;code&gt;.inc&lt;/code&gt; files treated as PHP files. Executing code out of context
	can be very dangerous, because it&#039;s unexpected and can lead to unknown
	results. However, if your modules consist of only variable assignments (as an
	example), this particular risk is mitigated.
&lt;/p&gt;
&lt;p&gt;
	允许 PHP 引擎直接处理这些模块可不是什么好主意。
	这包括如下两个方面，一、把你的模块都命名为使用 &lt;code&gt;.php&lt;/code&gt; 扩展名的文件名，
	二、通过 &lt;code&gt;AddType&lt;/code&gt; 指令让 Apache 把 &lt;code&gt;.inc&lt;/code&gt; 等同于 PHP 文件处理。
	在上下文外的环境执行这些代码很可能会很危险，因为这不是所预期的，而且可能会引起未知的后果。
	不过，如果这个模块只由一些变量赋值语句组成（就像上面的例子一样），这个风险还是很小的。
&lt;/p&gt;
&lt;p&gt;
	My favorite method for protecting your database access credentials is described
	in the &lt;em&gt;PHP Cookbook&lt;/em&gt; (O&#039;Reilly) by David Sklar and Adam Trachtenberg. Create
	a file, &lt;code&gt;/path/to/secret-stuff&lt;/code&gt;, that only &lt;code&gt;root&lt;/code&gt; can read (not &lt;code&gt;nobody&lt;/code&gt;) :
&lt;/p&gt;
&lt;p&gt;
	我最喜欢使用 David Sklar and Adam Trachtenberg 写的 &lt;em&gt;《PHP指导手册》&lt;/em&gt;（由 O&#039;Reilly 出版）
	一书中的方法来保护数据的连接信息。
	创建一个文件 &lt;code&gt;/path/to/secret-stuff&lt;/code&gt;，
	这个文件只有 &lt;code&gt;root&lt;/code&gt;（而不是 &lt;code&gt;nobody&lt;/code&gt;）能够访问到。
&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;SetEnv DB_USER &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;myuser&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;SetEnv DB_PASS &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;mypass&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;Include this file within &lt;code&gt;httpd.conf&lt;/code&gt; as follows:&lt;/p&gt;
&lt;p&gt;像下面这样把这个文件包含在 &lt;code&gt;httpd.conf&lt;/code&gt; 里：&lt;/p&gt;
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;Include&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;/path/to/secret-stuff&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	Now you can use &lt;code&gt;$_SERVER[&#039;DB_USER&#039;]&lt;/code&gt; and &lt;code&gt;$_SERVER[&#039;DB_PASS&#039;]&lt;/code&gt; in
	your code. Not only do you never have to write your username and password in
	any of your scripts, the Web server can&#039;t read the &lt;code&gt;secret-stuff&lt;/code&gt; file, so no
	other users can write scripts to read your access credentials (regardless of
	language). Just be careful not to expose these variables with something like
	&lt;code&gt;phpinfo()&lt;/code&gt; or &lt;code&gt;print_r($_SERVER)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
	现在，你可以在程序里面直接使用 &lt;code&gt;$_SERVER[&#039;DB_USER&#039;]&lt;/code&gt; 和 &lt;code&gt;$_SERVER[&#039;DB_PASS&#039;]&lt;/code&gt;。
	不仅你不用在任何程序里直接写用户名和密码，而且 Web 服务器也读不到 &lt;code&gt;secret-stuff&lt;/code&gt; 文件，
	这样，没有人能够写程序访问到你的连接信息了（不管是什么语言）。
	只需要小心不要让类似 &lt;code&gt;phpinfo()&lt;/code&gt; 或 &lt;code&gt;print_r($_SERVER)&lt;/code&gt; 这样的代码暴露这些变量信息。
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 18 Jun 2007 02:58:20 +0800</pubDate>
    <guid isPermaLink="false">http://blog.nulltao.net/archives/44-guid.html</guid>
    <category>php</category>
<category>security</category>
<category>translation</category>

</item>
<item>
    <title>PHP Security / Form Processing / Cross-Site Request Forgeries</title>
    <link>http://blog.nulltao.net/archives/43-PHP-Security-Form-Processing-Cross-Site-Request-Forgeries.html</link>
            <category>TranslatioN</category>
    
    <comments>http://blog.nulltao.net/archives/43-PHP-Security-Form-Processing-Cross-Site-Request-Forgeries.html#comments</comments>
    <wfw:comment>http://blog.nulltao.net/wfwcomment.php?cid=43</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.nulltao.net/rss.php?version=2.0&amp;type=comments&amp;cid=43</wfw:commentRss>
    

    <author>nulltao@gmail.com (Wei Geng)</author>
    <content:encoded>
    &lt;h3&gt;Cross-Site Request Forgeries&lt;/h3&gt;
&lt;h3&gt;跨站点请求伪造&lt;/H3&gt;
&lt;p&gt;
	Despite the similarities in name, cross-site request forgeries (CSRF) are an
	almost opposite style of attack. Whereas XSS attacks exploit the trust a user has
	in a Web site, CSRF attacks exploit the trust a Web site has in a user. CSRF
	attacks are more dangerous, less popular (which means fewer resources for
	developers), and more difficult to defend against than XSS attacks.
&lt;/p&gt;
&lt;p&gt;
	虽然和跨站点脚本攻击名字很相似，但是跨站点请求伪造是完全不同的攻击方法。
	XSS 攻击利用的是用户对网站的信任，CSRF 攻击利用的是网站对用户的信任。
	CSRF 攻击更加危险，更加不常见（也意味着对开发着可用的资源更少），
	和 XSS 攻击比起来也更加难以防范。
&lt;/p&gt;
&lt;p&gt;CSRF attacks have the following characteristics:&lt;/p&gt;
&lt;p&gt;CSRF 攻击有着如下的特征：&lt;/p&gt;
&lt;ul type=&quot;square&quot;&gt;
	&lt;li&gt;
		&lt;h4&gt;Exploit the trust that a site has for a particular user.&lt;/h4&gt;
		&lt;p&gt;
			Many users may not be trusted, but it is common for Web applications to
			offer users certain privileges upon logging in to the application. Users with
			these heightened privileges are potential victims (unknowing accomplices,
			in fact).
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;利用了站点对特定用户的信任。&lt;/h4&gt;
		&lt;p&gt;
			对于 Web 程序来说，很常见的一个现象就是大部分用户都不是可信的，
			只有通过登陆的用户才有更高级权限。这些有着更高权限的用户都是潜在的受害者
			（事实上，他们都不知道自己是同谋）。
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;Generally involve Web sites that rely on the identity of the users.&lt;/h4&gt;
		&lt;p&gt;
			It is typical for the identity of a user to carry a lot of weight. With a secure
			session management mechanism, which is a challenge in itself, CSRF
			attacks can still be successful. In fact, it is in these types of environments
			where CSRF attacks are most potent.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;通常都包含那些依赖用户身份的站点。&lt;/h4&gt;
		&lt;p&gt;
			让用户身份承担重要的作用是很典型的。即使在有安全的 session 管理机制的情况下，
			CSRF 攻击还是很容易成功的，况且这个机制本身还有疑问呢。事实上，
			正是在这种环境下 CSRF 攻击才最有说服力。
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;Perform HTTP requests of the attacker&#039;s choosing.&lt;/h4&gt;
		&lt;p&gt;
			CSRF attacks include all attacks that involve the attacker forging an HTTP
			request from another user (in essence, tricking a user into sending an
			HTTP request on the attacker&#039;s behalf). There are a few different
			techniques that can be used to accomplish this, and I will show some
			examples of one specific technique.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;h4&gt;执行攻击者所选择的 HTTP 请求。&lt;/h4&gt;
		&lt;p&gt;
			所有类型的，由攻击者把 HTTP 请求伪装成另外一个用户的，攻击都是 CSRF 攻击
			（其实质是，欺骗用户按照攻击者的意愿发送 HTTP 请求）。
			要执行这个攻击有几种技术可用，我会用一些例子来说明其中一个特别的技术。
		&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Because CSRF attacks involve the forging of HTTP requests, it is important to
	first gain a basic level of familiarity with HTTP.
&lt;/p&gt;
&lt;p&gt;因为 CSRF 攻击包含了 HTTP 请求伪造，所以当务之急是初步熟悉 HTTP。&lt;/p&gt;
&lt;p&gt;
	A Web browser is an HTTP client, and a Web server is an HTTP server. Clients
	initiate a transaction by sending a request, and the server completes the
	transaction by sending a response. A typical HTTP request is as follows:
&lt;/p&gt;
&lt;p&gt;
	Web 浏览器就是一个 HTTP 客户端，Web 服务器也就是一个 HTTP 服务器。
	客户端通过发送请求来发起一个事务，在服务器发送响应结果后事务结束。
	下面是一个典型的 HTTP 请求：
&lt;/p&gt;
&lt;div class=&quot;html4strict&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;GET / HTTP/1.1&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Host: example.org&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;User-Agent: Mozilla/5.0 Gecko&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Accept: text/xml, image/png, image/jpeg, image/gif, &lt;strong&gt;/*&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	The first line is called the request line, and it contains the request method,
	request URL (a relative URL is used), and HTTP version. The other lines are
	HTTP headers, and each header name is followed by a colon, a space, and the
	value.
&lt;/p&gt;
&lt;p&gt;
	第一行被称作请求行，这一行包含了请求的方式、请求的 URL（这里使用的是一个相对 URL）和 HTTP 版本号。
	其他的行都是 HTTP 头信息，每一个 HTTP 头的名字后面紧跟着一个冒号、一个空格和对应的值。
&lt;/p&gt;
&lt;p&gt;
	You might be familiar with accessing this information in PHP. For example, the
	following code can be used to rebuild this particular HTTP request:
&lt;/p&gt;
&lt;p&gt;
	你应该已经熟知如何用 PHP 来访问这些信息了。
	例如，下面的代码可以被用来重建上面这个特定的 HTTP 请求：
&lt;/p&gt;
[geshi lang=php in=y]&lt;?php
$request = &#039;&#039;;
$request .= &quot;{$_SERVER[&#039;REQUEST_METHOD&#039;]} &quot;;
$request .= &quot;{$_SERVER[&#039;REQUEST_URI&#039;]} &quot;;
$request .= &quot;{$_SERVER[&#039;SERVER_PROTOCOL&#039;]}\r\n&quot;;
$request .= &quot;Host: {$_SERVER[&#039;HTTP_HOST&#039;]}\r\n&quot;;
$request .= &quot;User-Agent: {$_SERVER[&#039;HTTP_USER_AGENT&#039;]}\r\n&quot;;
$request .= &quot;Accept: {$_SERVER[&#039;HTTP_ACCEPT&#039;]}\r\n\r\n&quot;;
?&gt;[/geshi]
&lt;p&gt;An example response to the previous request is as follows:&lt;/p&gt;
&lt;p&gt;如下是一个响应上面的请求的应答的例子：&lt;/p&gt;
&lt;div class=&quot;html4strict&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;HTTP/1.1 200 OK&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Content-Type: text/html&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Content-Length: 57&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/html.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/img.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;img&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #000066;&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;http://example.org/image.png&amp;quot;&lt;/span&gt; /&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	The content of a response is what you see when you view source in a browser.
	The &lt;code&gt;img&lt;/code&gt; tag in this particular response alerts the browser to the fact that another
	resource (an image) is necessary to properly render the page. The browser
	requests this resource as it would any other, and the following is an example of
	such a request:
&lt;/p&gt;
&lt;p&gt;
	你在浏览器里面察看源代码的时候所看到的就是响应的内容。
	在这个特定的响应里的 &lt;code&gt;img&lt;/code&gt; 标签，告诉浏览器要正确的生成这个页面，还需要请求另外一个资源（这个图片）。
	浏览器和请求其他资源一样请求这个资源，下面就是这个请求的例子：
&lt;/p&gt;
&lt;div class=&quot;html4strict&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;GET /image.png HTTP/1.1&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Host: example.org&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;User-Agent: Mozilla/5.0 Gecko&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;Accept: text/xml, image/png, image/jpeg, image/gif, &lt;/strong&gt;/*&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	This is worthy of attention. The browser requests the URL specified in the &lt;code&gt;src&lt;/code&gt;
	attribute of the &lt;code&gt;img&lt;/code&gt; tag just as if the user had manually navigated there. The
	browser has no way to specifically indicate that it expects an image.
&lt;/p&gt;
&lt;p&gt;
	这一段值得注意一下。浏览器请求在 &lt;code&gt;img&lt;/code&gt; 标签的 &lt;code&gt;src&lt;/code&gt; 属性里指定的 URL，
	就如同用户手工定向到那里。浏览器无法明确指出请求的是一个图片。
&lt;/p&gt;
&lt;p&gt;
	Combine this with what you&#039;ve learned about forms, and then consider a URL
	similar to the following:
&lt;/p&gt;
&lt;p&gt;把这些和你以前学到的关于表单的知识结合起来，然后看一个和下面累死的 URL：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://stocks.example.org/buy.php?symbol=SCOX&amp;quantity=1000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	A form submission that uses the GET method can potentially be indistinguishable
	from an image request – both could be requests for the same URL. If
	&lt;code&gt;register_globals&lt;/code&gt; is enabled, the method of the form isn&#039;t even important
	(unless the developer still uses &lt;code&gt;$_POST&lt;/code&gt; and the like). Hopefully the dangers are
	already becoming clear.
&lt;/p&gt;
&lt;p&gt;
	很可能无法把一个使用 GET 方式提交的表单和一个图片请求区分开来——因为这两者都可以以同样的 URL 发送请求。
	如果启用了 &lt;code&gt;register_globals&lt;/code&gt; 选项，标单提交的方法也都不重要了
	（除非开发者还在使用 &lt;code&gt;$_POST&lt;/code&gt; 或者类似的变量）。看起来危险已经变清晰了。
&lt;/p&gt;
&lt;p&gt;
	Another characteristic that makes CSRF so powerful is that any cookies
	pertaining to a URL are included in the request for that URL. A user who has an
	established relationship with &lt;code&gt;stocks.example.org&lt;/code&gt; (such as being logged in)
	can potentially buy 1000 shares of SCOX by visiting a page with an &lt;code&gt;img&lt;/code&gt; tag that
	specifies the URL in the previous example.
&lt;/p&gt;
&lt;p&gt;
	很多附属于一个 URL 的 cookie 都被对那个 URL 的请求所包含，这是另外一个让 CSRF 如此危险的特征。
	一个和 &lt;code&gt;stocks.example.org&lt;/code&gt; 建立了连接的用户（例如登陆后），
	可以通过访问一个页面来买 1000 股 SCOX 股票，这个页面需要有一个 &lt;code&gt;img&lt;/code&gt; 标签，
	而这个标签指定要访问上面例子中的的 URL。
&lt;/p&gt;
&lt;p&gt;
	Consider the following form located (hypothetically) at
	&lt;code&gt;http://stocks.example.org/form.html&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;看下面这个（假设）位于 &lt;code&gt;http://stocks.example.org/form.html&lt;/code&gt; 的表单：&lt;/p&gt;
&lt;div class=&quot;html4strict&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/p.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;Buy Stocks Instantly!&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/form.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;form&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #000066;&quot;&gt;action&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;/buy.php&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/p.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;Symbol:&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/input.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;input&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #000066;&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;symbol&amp;quot;&lt;/span&gt; /&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/p.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;Quantity:&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/input.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;input&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #000066;&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;quantity&amp;quot;&lt;/span&gt; /&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;a href=&quot;http://december.com/html/4/element/input.html&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;input&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #000066;&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; /&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	If the user enters &lt;code&gt;SCOX&lt;/code&gt; for the symbol, &lt;code&gt;1000&lt;/code&gt; as the quantity, and submits the
	form, the request that is sent by the browser is similar to the following:
&lt;/p&gt;
&lt;p&gt;
	如果用户在 symbol 框里面输入 &lt;code&gt;SCOX&lt;/code&gt;，在 quantity 框输入 &lt;code&gt;1000&lt;/code&gt;，然后提交这个表单，
	浏览器会发出和下面相似的请求：
&lt;/p&gt;
&lt;div class=&quot;html4strict&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;GET /buy.php?symbol=SCOX&lt;span style=&quot;color: #ddbb00;&quot;&gt;&amp;amp;quantity=1000 HTTP/1.1&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ddbb00;&quot;&gt;Host: stocks.example.org&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ddbb00;&quot;&gt;User-Agent: Mozilla/5.0 Gecko&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ddbb00;&quot;&gt;Accept: text/xml, image/png, image/jpeg, image/gif, */*&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ddbb00;&quot;&gt;Cookie: PHPSESSID=1234&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #ddbb00;&quot;&gt;&lt;/span&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;
	I include a &lt;code&gt;Cookie&lt;/code&gt; header in this example to illustrate the application using a
	cookie for the session identifier. If an &lt;code&gt;img&lt;/code&gt; tag references the same URL, the
	same cookie will be sent in the request for that URL, and the server processing
	the request will be unable to distinguish this from an actual order.
&lt;/p&gt;
&lt;p&gt;
	我在这个例子的头信息里面包含