<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>玄猫的窝-韩国峰的博客 &#187; 翻译</title>
	<atom:link href="http://www.hanguofeng.cn/tag/%e7%bf%bb%e8%af%91/feed" rel="self" type="application/rss+xml" />
	<link>http://www.hanguofeng.cn</link>
	<description>韩国峰的博客,关注Web技术与电子商务。</description>
	<lastBuildDate>Sat, 04 Sep 2010 14:39:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>SQL注入攻击-来自微软安全博客的建议</title>
		<link>http://www.hanguofeng.cn/archives/security/sql-injection-attack?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=sql-injection-attack</link>
		<comments>http://www.hanguofeng.cn/archives/security/sql-injection-attack#comments</comments>
		<pubDate>Tue, 03 Jun 2008 12:33:39 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[网络安全]]></category>
		<category><![CDATA[SQL Injection]]></category>
		<category><![CDATA[SQL注入]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/archives/security/sql-injection-attack</guid>
		<description><![CDATA[本文翻译自微软博客上刊载的相关文章，英文原文版权归原作者所有，特此声明。 原文：http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx 本文译言地址：http://www.yeeyan.com/articles/view/hanguofeng/8955 （特别感谢Neil Carpenter对本文写作提供的帮助） 近期趋势 从去年下半年开始，很多网站被损害，他们在用于生成动态网页的SQL数据库中存储的文本中被注入了恶意的HTML &#60;script&#62;标签。这样的攻击在2008年第一季度开始加速传播，并且持续影响有漏洞的Web程序。 这些Web应用程序有这样一些共同点： 使用经典ASP代码的程序 使用SQL Server数据库的程序 应用程序代码根据URI请求字符动态地生成SQL查询（http://consoto.com/widgets.asp?widget=sprocket）这体现了一种新的SQL注入（SQL injection）的途径（http://msdn.microsoft.com/en-us/library/ms161953.aspx）。在过去，SQL注入攻击的目标是具有如下特点的特殊Web应用程序：攻击者知道或者可以探测出后台数据库的漏洞或者结构。这样的攻击（指本文讨论的攻击-译者注）不同，因为它是抽象的，对于攻击来说，任何存在于使用URI请求字符串动态创建SQL查询的ASP页面都可能存在。你可以在 http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx找到更多的技术详情和简单代码。 这样的攻击并非利用了Window、IIS、SQL Server或者其他底层代码的漏洞，而是利用了在这些平台上运行的由程序员自行编写的代码中的漏洞。Microsoft已经对这些攻击进行了彻底的调查，并且发现，他们和以往的Microsoft产品的补丁和0-day漏洞无关。你可以在http://blogs.technet.com/msrc/archive/2008/04/25/questions-about-web-server-attacks.aspx获取跟多的信息。  正如上面所指出的，这些攻击在近年来呈现一种增长的趋势。这至少与两个因素有关： 第一，有暴力性的恶意攻击工具自动化进行此类操作。SANS在http://isc.sans.org/diary.html?storyid=4294讨论了这类工具。该工具使用搜索引擎来寻找具有SQL注入漏洞的站点。 第二，一个或多个恶意僵尸正在进行SQL注入攻击，用以广泛传播僵尸。SecureWorks在http://www.secureworks.com/research/threats/danmecasprox/讨论了一个案例。 一旦某台服务器被该漏洞所攻击，它将被插入指向某.js文件的恶意&#60;script&#62;标签。虽然这些文件的内容不同，但是他们都尝试利用已经被修复的Micfosoft产品的漏洞或者第三方ActiveX控件的漏洞。由于这些脚本被单独存储，这些脚本就很容易的被更新以利用更新的客户端漏洞，也更容易按照不同浏览器来定制。 给信息技术/数据库管理员的建议 有很多事情是信息技术管理员或者数据库管理员可以采取的，以减少他们的风险和响应他们的代码和平台中可能出现的事件： 检查IIS日志和数据表来寻找未知风险的标志。 由于该漏洞利用方式通过URI请求字符串作用，管理员们可以检查IIS日志来查找尝试利用该漏洞的非正常请求。你可以在http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx找到如何手动进行改操作的详细信息。在 http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&#38;ReleaseId=13436有进行自动化操作的工具。 如果IIS日志表明服务器可能已经被侵害，那么下一步要采取的行动就是审计相应的Web应用程序所使用的数据库中的表，并且查找附加在文本内容中的&#60;script&#62;标签。 提示：IIS服务器不应当在生产环境中关闭日志。存储和适当的管理对于IIS日志都是重要的，缺少IIS日志对于响应安全事件是非常困难的。 如果运行了使用后端数据库的第三方代码，则考虑不受SQL注入影响的独立软件开发商（ISV，Independent Software Vendors）。 在使用第三方ASP Web程序的情况下，管理员应当联系应用程序厂商来确定他们的产品不受SQL注入攻击的影响。 确认Web应用程序所使用的数据库帐户具有最少的权限。 管理员应当确保Web应用程序所使用的SQL用户具有最小的必要权限。Web应用程序不应当以诸如&#8221;sysadmin&#8221;的服务器管理员权限或者&#8221;db_owner&#8221;的数据库权限链接。白皮书&#8221;在SQL Server 2005中的最优化安全设置和维护&#8221;： http://download.microsoft.com/download/8/5/e/85eea4fa-b3bb-4426-97d0-7f7151b2011c/SQL2005SecBestPract.doc 提供了关于SQL Server安全的多方面建议。 给Web开发者的建议 有很多优秀的文档论述在编码时如何防御SQL注入攻击。由于这些攻击者leverage有漏洞的Web应用程序代码，所以完全防御他们的唯一方法是解析在代码中存在的漏洞。程序中任何一个使用外部资源（一般指从URI请求字符串）数据来动态生成SQL请求的地方都应当被认为是可疑的。当代码漏洞被识别出来，他们应当被小心的修复。 说明-SQL注入、ASP.NET和ADO.NET ： http://msdn.microsoft.com/en-us/library/bb671351.aspx 同时，上面的文章包含到相关文章&#8221;如何在ASP.NET中避免SQL注入&#8221; http://msdn.microsoft.com/en-us/library/ms998271.aspx，该文章同时适用于ASP。 这里有一个非常有用的视频（该视频是针对一篇防御文章的，然而链接可能已经无效了）：http://channel9.msdn.com/wiki/default.aspx/SecurityWiki.SQLInjectionLab。 关于SQL注入如何实现的简单信息： http://msdn.microsoft.com/en-us/library/ms161953.aspx ASP代码中的SQL注入（与ASP.NET中的并不相同）： http://msdn.microsoft.com/en-us/library/cc676512.aspx 如何在ASP中执行SQL Server存储过程： http://support.microsoft.com/kb/q164485 Microsoft安全部门（The [...]]]></description>
			<content:encoded><![CDATA[<p>本文翻译自微软博客上刊载的相关文章，英文原文版权归原作者所有，特此声明。</p>
<p>原文：<a href="http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx">http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx</a></p>
<p>本文译言地址：<a href="http://www.yeeyan.com/articles/view/hanguofeng/8955">http://www.yeeyan.com/articles/view/hanguofeng/8955</a></p>
<p><span id="more-19"></span></p>
<p>（特别感谢<a href="http://blogs.technet.com/neilcar">Neil Carpenter</a>对本文写作提供的帮助）</p>
<h2>近期趋势</h2>
<p>从去年下半年开始，很多网站被损害，他们在用于生成动态网页的SQL数据库中存储的文本中被注入了恶意的HTML &lt;script&gt;标签。这样的攻击在2008年第一季度开始加速传播，并且持续影响有漏洞的Web程序。<br />
这些Web应用程序有这样一些共同点：</p>
<ul>
<li>使用经典ASP代码的程序</li>
<li>使用SQL Server数据库的程序</li>
</ul>
<p>应用程序代码根据URI请求字符动态地生成SQL查询（http://consoto.com/widgets.asp<strong>?widget=sprocket</strong>）这体现了一种新的SQL注入（SQL injection）的途径（<a href="http://msdn.microsoft.com/en-us/library/ms161953.aspx">http://msdn.microsoft.com/en-us/library/ms161953.aspx</a>）。在过去，SQL注入攻击的目标是具有如下特点的特殊Web应用程序：攻击者知道或者可以探测出后台数据库的漏洞或者结构。这样的攻击（指本文讨论的攻击-译者注）不同，因为它是抽象的，对于攻击来说，任何存在于使用URI请求字符串动态创建SQL查询的ASP页面都可能存在。你可以在 <a href="http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx">http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx</a>找到更多的技术详情和简单代码。</p>
<p>这样的攻击并非利用了Window、IIS、SQL Server或者其他底层代码的漏洞，而是利用了在这些平台上运行的由程序员自行编写的代码中的漏洞。Microsoft已经对这些攻击进行了彻底的调查，并且发现，他们和以往的Microsoft产品的补丁和0-day漏洞无关。你可以在<span style="text-decoration: underline;"><a href="http://blogs.technet.com/msrc/archive/2008/04/25/questions-about-web-server-attacks.aspx">http://blogs.technet.com/msrc/archive/2008/04/25/questions-about-web-server-attacks.aspx</a></span>获取跟多的信息。</p>
<p> 正如上面所指出的，这些攻击在近年来呈现一种增长的趋势。这至少与两个因素有关：</p>
<p>第一，有暴力性的恶意攻击工具自动化进行此类操作。SANS在<a href="http://isc.sans.org/diary.html?storyid=4294">http://isc.sans.org/diary.html?storyid=4294</a>讨论了这类工具。该工具使用搜索引擎来寻找具有SQL注入漏洞的站点。</p>
<p>第二，一个或多个恶意僵尸正在进行SQL注入攻击，用以广泛传播僵尸。SecureWorks在<a href="http://www.secureworks.com/research/threats/danmecasprox/">http://www.secureworks.com/research/threats/danmecasprox/</a>讨论了一个案例。</p>
<p>一旦某台服务器被该漏洞所攻击，它将被插入指向某.js文件的恶意&lt;script&gt;标签。虽然这些文件的内容不同，但是他们都尝试利用已经被修复的Micfosoft产品的漏洞或者第三方ActiveX控件的漏洞。由于这些脚本被单独存储，这些脚本就很容易的被更新以利用更新的客户端漏洞，也更容易按照不同浏览器来定制。</p>
<h2>给信息技术/数据库管理员的建议</h2>
<p>有很多事情是信息技术管理员或者数据库管理员可以采取的，以减少他们的风险和响应他们的代码和平台中可能出现的事件：</p>
<ul>
<li><strong>检查IIS日志和数据表来寻找未知风险的标志。</strong></li>
</ul>
<p>由于该漏洞利用方式通过URI请求字符串作用，管理员们可以检查IIS日志来查找尝试利用该漏洞的非正常请求。你可以在<a href="http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx">http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx</a>找到如何手动进行改操作的详细信息。在 <a href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;ReleaseId=13436">http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;ReleaseId=13436</a>有进行自动化操作的工具。</p>
<p>如果IIS日志表明服务器可能已经被侵害，那么下一步要采取的行动就是审计相应的Web应用程序所使用的数据库中的表，并且查找附加在文本内容中的&lt;script&gt;标签。</p>
<p>提示：IIS服务器不应当在生产环境中关闭日志。存储和适当的管理对于IIS日志都是重要的，缺少IIS日志对于响应安全事件是非常困难的。</p>
<ul>
<li><strong>如果运行了使用后端数据库的第三方代码，则考虑不受SQL注入影响的独立软件开发商（ISV，Independent Software Vendors）。</strong></li>
</ul>
<p>在使用第三方ASP Web程序的情况下，管理员应当联系应用程序厂商来确定他们的产品不受SQL注入攻击的影响。</p>
<ul>
<li><strong>确认Web应用程序所使用的数据库帐户具有最少的权限。</strong></li>
</ul>
<p>管理员应当确保Web应用程序所使用的SQL用户具有最小的必要权限。Web应用程序不应当以诸如&#8221;sysadmin&#8221;的服务器管理员权限或者&#8221;db_owner&#8221;的数据库权限链接。白皮书&#8221;在SQL Server 2005中的最优化安全设置和维护&#8221;： <span style="text-decoration: underline;"><a href="http://download.microsoft.com/download/8/5/e/85eea4fa-b3bb-4426-97d0-7f7151b2011c/SQL2005SecBestPract.doc">http://download.microsoft.com/download/8/5/e/85eea4fa-b3bb-4426-97d0-7f7151b2011c/SQL2005SecBestPract.doc</a></span> 提供了关于SQL Server安全的多方面建议。</p>
<h2>给Web开发者的建议</h2>
<p>有很多优秀的文档论述在编码时如何防御SQL注入攻击。由于这些攻击者leverage有漏洞的Web应用程序代码，所以完全防御他们的唯一方法是解析在代码中存在的漏洞。程序中任何一个使用外部资源（一般指从URI请求字符串）数据来动态生成SQL请求的地方都应当被认为是可疑的。当代码漏洞被识别出来，他们应当被小心的修复。</p>
<ul>
<li><strong>说明</strong><strong>-SQL</strong><strong>注入、</strong><strong>ASP.NET</strong><strong>和</strong><strong>ADO.NET</strong> <strong>：</strong></li>
</ul>
<p><a href="http://msdn.microsoft.com/en-us/library/bb671351.aspx">http://msdn.microsoft.com/en-us/library/bb671351.aspx</a><br />
同时，上面的文章包含到相关文章&#8221;如何在ASP.NET中避免SQL注入&#8221; <a href="http://msdn.microsoft.com/en-us/library/ms998271.aspx">http://msdn.microsoft.com/en-us/library/ms998271.aspx</a>，该文章同时适用于ASP。</p>
<p>这里有一个非常有用的视频（该视频是针对一篇防御文章的，然而链接可能已经无效了）：<a href="http://channel9.msdn.com/wiki/default.aspx/SecurityWiki.SQLInjectionLab">http://channel9.msdn.com/wiki/default.aspx/SecurityWiki.SQLInjectionLab</a>。</p>
<ul>
<li><strong>关于</strong><strong>SQL</strong><strong>注入如何实现的简单信息：</strong></li>
</ul>
<p><a href="http://msdn.microsoft.com/en-us/library/ms161953.aspx">http://msdn.microsoft.com/en-us/library/ms161953.aspx</a></p>
<ul>
<li><strong>ASP</strong><strong>代码中的SQL注入（与ASP.NET中的并不相同）：</strong></li>
</ul>
<p><a href="http://msdn.microsoft.com/en-us/library/cc676512.aspx">http://msdn.microsoft.com/en-us/library/cc676512.aspx</a><br />
如何在ASP中执行SQL Server存储过程： <a href="http://support.microsoft.com/kb/q164485">http://support.microsoft.com/kb/q164485</a></p>
<ul>
<li><strong>Microsoft</strong><strong>安全部门（The Microsoft Security Development Lifecycle,SDL）对SQL注入的防御进行了一些指导。简单来说有三种策略来应对SQL注入攻击：</strong></li>
</ul>
<ol>
<li>使用SQL参数查询</li>
<li>使用存储过程</li>
<li>使用SQL仅执行（execute-only）许可</li>
</ol>
<p>Michael Howard在<a href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx">http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx</a>谈论了这些内容。</p>
<p>同时，编写安全的代码（第二版）也指导了如何防御此类攻击（请浏览399-411页）。</p>
<ul>
<li><strong>减轻SQL注入：使用参数查询（第一部分和第二部分）。使用参数化查询的好处是它将执行的代码（例如SELECT语句）和数据（由程序使用者提供的动态信息）分开。该途径防御了通过用户传递来执行的恶意语句。</strong></li>
</ul>
<p>第一部分：<br />
<a href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx">http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx</a></p>
<p>第二部分：<br />
<a href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx">http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx</a></p>
<p>在经典ASP代码中过滤SQL注入（或者黑名单中的字符），我们将如下的工作认为是实际中临时性的解决方案，因为它治标不治本。（例如，代码仍然是有漏洞的，他仍然可能被绕过过滤机制而被访问到）<br />
IIS团队中的Nazim解释了如何过滤的详细信息：<a href="http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx">http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx</a>。</p>
<p>如果你仍然不了解从哪里开始，所有使用特定ASP代码访问数据库，尤其是使用由用户提供的数据的代码应当首先被检测。</p>
<h2>给最终用户的建议</h2>
<p>最终用户（下简称用户-译者注）应当浏览位于<a href="http://www.microsoft.com/protect/default.mspx">http://www.microsoft.com/protect/default.mspx</a>的信息。另外，这里也有一些你可以采取以保护自己的步骤。</p>
<ul>
<li><strong>通常应当有选择的访问网站-但是也需要了解，该漏洞也会影响用户信任的网站。</strong></li>
</ul>
<p>有选择的访问网站减少了你暴露在漏洞下的风险，当然即使是你所信任的也有可能被攻击。留意不正常的行为，了解面临的风险，并且实施本节提供的其他建议。</p>
<ul>
<li><strong>针对Microsoft和第三方软件，保持安全更新。</strong></li>
</ul>
<p>由于恶意代码通常利用了已知的漏洞，因此你应当确保你在运行最新进行安全更新过的的Microsoft和第三方软件。Microsoft安全更新可以通过<a href="http://update.microsoft.com/">http://update.microsoft.com</a>了解。<a href="http://www.microsoft.com/protect/computer/updates/OS.aspx">http://www.microsoft.com/protect/computer/updates/OS.aspx</a>有更多信息。</p>
<ul>
<li><strong>禁用不必要的ActiveX控件和IE加载项。</strong></li>
</ul>
<p>你应当禁用所有不必要的ActiveX控件和IE加载项。根据KB883256（<a href="http://support.microsoft.com/kb/883256">http://support.microsoft.com/kb/883256</a>）的方法在Windows XP Service Pack2或者更新版本中来实施本步骤：</p>
<ol>
<li>打开IE。</li>
<li>在&#8221;工具&#8221;菜单点击管理加载项。</li>
<li>点击加载项的名称。</li>
<li>使用如下的方法：
<ul>
<li>点击更新ActiveX来使用最新的版本替换该控件。这个方法并非对所有的加载项都可用。</li>
<li>点击&#8221;启用&#8221;，而后点击&#8221;确定&#8221;，来启用加载项。</li>
<li>点击&#8221;禁用&#8221;，而后点击&#8221;确定&#8221;，来禁用加载项。</li>
</ul>
</li>
</ol>
<p>你可能需要重启IE来确保在启用/禁用插件的操作成功。<br />
针对更糟的操作系统，根据KB154036（<a href="http://support.microsoft.com/kb/154036">http://support.microsoft.com/kb/154036</a>）的说明进行操作。</p>
<ul>
<li><strong>减少你所使用的第三方浏览器的受攻击风险的步骤。</strong></li>
</ul>
<p>如果你使用了IE之外的浏览器，那么你应当确保你安装的是最新的安全更新版本，同时你应当禁用了不必要的扩展和加载项。流行浏览器的信息可以在如下链接找到：</p>
<p>Firefox &#8211; <a href="http://support.mozilla.com/en-US/kb/Firefox+Support+Home+Page">http://support.mozilla.com/en-US/kb/Firefox+Support+Home+Page</a><br />
Opera &#8211; <a href="http://www.opera.com/support/">http://www.opera.com/support/</a><br />
Safari &#8211; <a href="http://www.apple.com/support/safari/">http://www.apple.com/support/safari/</a></p>
<ul>
<li><strong>更新反恶意程序软件</strong></li>
</ul>
<p>用户应当确保已经安装了杀毒软件和反间谍软件，并且保持他们的更新。你可以在<a href="http://www.microsoft.com/protect/computer/antivirus/OS.aspx">http://www.microsoft.com/protect/computer/antivirus/OS.aspx</a>和<a href="http://www.microsoft.com/protect/computer/antispyware/OS.aspx">http://www.microsoft.com/protect/computer/antispyware/OS.aspx</a>找到更多信息。你可以在 <a href="http://onecare.live.com/standard/en-us/install/install.htm">http://onecare.live.com/standard/en-us/install/install.htm</a>得到一份90天使用的Windows Live OneCare杀毒/反间谍软件。</p>
<p class="zoundry_raven_tags"><!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --><span class="ztags"><span class="ztagspace">Del.icio.us</span> : <a class="ztag" rel="tag" href="http://del.icio.us/tag/SQL%20Injection">SQL Injection</a>, <a class="ztag" rel="tag" href="http://del.icio.us/tag/SQL%E6%B3%A8%E5%85%A5">SQL注入</a>, <a class="ztag" rel="tag" href="http://del.icio.us/tag/%E7%BF%BB%E8%AF%91">翻译</a></span></p>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference" title="[译文]Google AJAX Language API对象参考">[译文]Google AJAX Language API对象参考</a></li><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide" title="[译文]Google AJAX Language API开发者参考">[译文]Google AJAX Language API开发者参考</a></li><li><a href="http://www.hanguofeng.cn/archives/security/preventing-csrf" title="[译文]防止CSRF攻击">[译文]防止CSRF攻击</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/security/sql-injection-attack/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[译文]Google AJAX Language API对象参考</title>
		<link>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-ajax-language-api-class-reference</link>
		<comments>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference#comments</comments>
		<pubDate>Sat, 22 Mar 2008 12:25:51 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web客户端技术]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference</guid>
		<description><![CDATA[原文：http://code.google.com/apis/ajaxlanguage/documentation/reference.html 译言链接：http://www.yeeyan.com/articles/view/hanguofeng/5896 对象参考 全局方法 方法 返回类型 描述 google.language.translate(text, srcLang, destLang, callback) 无 全局方法，返回对支持的给定文本的目标语言翻译匹配文本。结果支持通过指定的callback函数进行异步调用。 text &#8211; 要翻译的文本。 srcLang &#8211; 以语言代码形式表现的源语言。参考Language 枚举。如果改惨啊数是一个空字符串，则系统将尝试自动识别源语言。 destLang &#8211; 以语言代码形式表现的目标语言。参考Language 枚举。 callback &#8211; 接收结果的回调函数。 google.language.detect(text, callback) 无 全局方法，返回描述给定语言文本的语言代码。结果支持通过指定的callback函数进行异步调用。 text &#8211; 要翻译的文本 callback -接收结果的回调函数。 结果对象 翻译结果 &#60;result&#62; error?在载入feed时是否出现错误 codeHTTP风格的错误代码 message便与人阅读的错误描述文本 translation翻译后的文本 检测结果 &#60;result&#62; error?在载入feed时是否出现错误 codeAn HTTP风格的错误代码 message便与人阅读的错误描述文本 language给定语言的语言代码。参考Language 枚举 isReliable一个布尔型变量来描述给定文本是否是可靠的 confidence一个基于0-1.0之间的数值，用来描述对给定文本的可信级别 Language枚举 google [...]]]></description>
			<content:encoded><![CDATA[<p>原文：<a href="http://code.google.com/apis/ajaxlanguage/documentation/reference.html">http://code.google.com/apis/ajaxlanguage/documentation/reference.html</a></p>
<p>译言链接：<a href="http://www.yeeyan.com/articles/view/hanguofeng/5896">http://www.yeeyan.com/articles/view/hanguofeng/5896</a><span id="more-12"></span></p>
<h1>对象参考</h1>
<h2>全局方法</h2>
<table border="1" width="500" cellPadding="0" cellSpacing="0">
<tr>
<td width="200" vAlign="top">
<p align="center"><strong>方法</strong></p>
</td>
<td width="50" vAlign="top">
<p align="center"><strong>返回类型</strong></p>
</td>
<td width="250" vAlign="top">
<p align="center"><strong>描述</strong></p>
</td>
</tr>
<tr>
<td width="187" vAlign="top">google.language.translate(text, srcLang, destLang, callback)</td>
<td width="77" vAlign="top">无</td>
<td width="289" vAlign="top">全局方法，返回对支持的给定文本的目标语言翻译匹配文本。结果支持通过指定的callback函数进行异步调用。</p>
<ul>
<li><strong>text</strong> &#8211; 要翻译的文本。</li>
<li><strong>srcLang</strong> &#8211; 以语言代码形式表现的源语言。参考Language 枚举。如果改惨啊数是一个空字符串，则系统将尝试自动识别源语言。</li>
<li><strong>destLang</strong> &#8211; 以语言代码形式表现的目标语言。参考Language 枚举。</li>
<li><strong>callback</strong> &#8211; 接收结果的回调函数。</li>
</ul>
</td>
</tr>
<tr>
<td width="187" vAlign="top">google.language.detect(text, callback)</td>
<td width="77" vAlign="top">无</td>
<td width="289" vAlign="top">全局方法，返回描述给定语言文本的语言代码。结果支持通过指定的callback函数进行异步调用。</p>
<ul>
<li><strong>text</strong> &#8211; 要翻译的文本</li>
<li><strong>callback</strong> -接收结果的回调函数。</li>
</ul>
</td>
</tr>
</table>
<h2>结果对象</h2>
<h3>翻译结果</h3>
<ul class="json">
<li>&lt;result&gt;
<ul>
<li>error?在载入feed时是否出现错误
<ul>
<li>code<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP风格的错误代码</a></li>
<li>message便与人阅读的错误描述文本</li>
</ul>
</li>
<li>translation翻译后的文本</li>
</ul>
</li>
</ul>
<h3>检测结果</h3>
<ul class="json">
<li>&lt;result&gt;
<ul>
<li>error?在载入feed时是否出现错误
<ul>
<li>codeAn <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP风格的错误代码</a></li>
<li>message便与人阅读的错误描述文本</li>
</ul>
</li>
<li>language给定语言的语言代码。参考Language 枚举</li>
<li>isReliable一个布尔型变量来描述给定文本是否是可靠的</li>
<li>confidence一个基于0-1.0之间的数值，用来描述对给定文本的可信级别</li>
</ul>
</li>
</ul>
<h3>Language枚举</h3>
<p>google language的language枚举提供了对于名称常量到语言代码的映射，用来描述srcLang和destLang参数。以下是用在Google Translate的相同代码：</p>
<pre class="prettyprint">
var google.language.Languages = {

  'ENGLISH' : 'en',

  'CHINESE' : 'zh',

  'CHINESE_SIMPLIFIED' : 'zh-CN',

  'CHINESE_TRADITIONAL' : 'zh-TW',

  'ARABIC' : 'ar',

  'FRENCH' : 'fr',

  'GERMAN' : 'de',

  'ITALIAN' : 'it',

  'JAPANESE' : 'ja',

  'KOREAN' : 'ko',

  'PORTUGUESE' : 'pt-PT',

  'RUSSIAN' : 'ru',

  'SPANISH' : 'es',

  'DUTCH': 'nl',

  'UNKNOWN' : ''

};</pre>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide" title="[译文]Google AJAX Language API开发者参考">[译文]Google AJAX Language API开发者参考</a></li><li><a href="http://www.hanguofeng.cn/archives/security/sql-injection-attack" title="SQL注入攻击-来自微软安全博客的建议">SQL注入攻击-来自微软安全博客的建议</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/google-language-for-wordpress" title="Google Language for WordPress">Google Language for WordPress</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译文]Google AJAX Language API开发者参考</title>
		<link>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-ajax-language-api-developers-guide</link>
		<comments>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide#comments</comments>
		<pubDate>Sat, 22 Mar 2008 12:13:15 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web客户端技术]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide</guid>
		<description><![CDATA[原文：http://code.google.com/apis/ajaxlanguage/documentation/ 译言链接：http://www.yeeyan.com/articles/view/hanguofeng/5895 开发者参考 使用AJAX Language API，你可以仅使用JavaScript来完成对某个网页上某个区域的语言进行翻译和检测的工作。 API是新开发的，因此相对于一个完美的文档来说，可能有一些bug和微小的不足。我们会修补这些漏洞，因此请谅解、你可以加入AJAX APIs开发者论坛来给我们反馈和讨论这个API。 面向读者 本文档是面向对JavaScript编程和面向对象编程概念有所了解的人准备的。在互联网上有很多JavaScript教程。 介绍 在Google Ajax Language API上的&#8221;Hello,World&#8221;程序 开始学习本API的最简单方法是来看一个简单的例子，一下案例将检测给定语言，并且将其翻译为英文。 &#60;html&#62;   &#60;head&#62;   &#60;script type="text/javascript" src="http://www.google.com/jsapi"&#62;&#60;/script&#62;   &#60;script type="text/javascript"&#62; google.load("language", "1"); function initialize() {   var text = document.getElementById("text").innerHTML;   google.language.detect(text, function(result) {   if (!result.error &#38;&#38; result.language) {   google.language.translate(text, result.language, "en",   function(result) {   var [...]]]></description>
			<content:encoded><![CDATA[<p>原文：<a href="http://code.google.com/apis/ajaxlanguage/documentation/">http://code.google.com/apis/ajaxlanguage/documentation/</a></p>
<p>译言链接：<a href="http://www.yeeyan.com/articles/view/hanguofeng/5895">http://www.yeeyan.com/articles/view/hanguofeng/5895</a><br />
<span id="more-11"></span></p>
<h1>开发者参考</h1>
<p>使用AJAX Language API，你可以仅使用JavaScript来完成对某个网页上某个区域的语言进行翻译和检测的工作。</p>
<p>API是新开发的，因此相对于一个完美的文档来说，可能有一些bug和微小的不足。我们会修补这些漏洞，因此请谅解、你可以加入<a href="http://groups.google.com/group/Google-AJAX-Search-API">AJAX APIs开发者论坛</a>来给我们反馈和讨论这个API。</p>
<h2>面向读者</h2>
<p>本文档是面向对JavaScript编程和面向对象编程概念有所了解的人准备的。在互联网上有很多<a href="http://www.google.com/search?q=javascript+tutorials">JavaScript教程</a>。</p>
<h2>介绍</h2>
<h3>在Google Ajax Language API上的&#8221;Hello,World&#8221;程序</h3>
<p>开始学习本API的最简单方法是来看一个简单的例子，一下案例将检测给定语言，并且将其翻译为英文。</p>
<pre class="prettyprint">
&lt;html&gt;

  &lt;head&gt;

    &lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;

    &lt;script type="text/javascript"&gt;    google.load("language", "1");

function initialize() {

      var text = document.getElementById("text").innerHTML;

      google.language.detect(text, function(result) {

        if (!result.error &amp;&amp; result.language) {

   google.language.translate(text, result.language, "en",

                             function(result) {

     var translated = document.getElementById("translation");

     if (result.translation) {

       translated.innerHTML = result.translation;

            }

          });

        }

      });

    }

    google.setOnLoadCallback(initialize);

&lt;/script&gt;

  &lt;/head&gt;

  &lt;body&gt;

    &lt;div id="text"&gt;你好，很高興見到你。&lt;/div&gt;

    &lt;div id="translation"&gt;&lt;/div&gt;

  &lt;/body&gt;

&lt;/html&gt;</pre>
<p>你可以<a href="http://code.google.com/apis/ajaxlanguage/documentation/helloworld.html">在这里查看该案例</a>，并且随意修改和运行它。</p>
<h3>在你的网页中包含Ajax Language API</h3>
<p>为了在你的网页中加入AJAX Language API，你需要利用<a href="http://code.google.com/apis/ajax/documentation/">Google AJAX API Loader</a>。该公有加载类允许你加载你所需要的所有AJAX API，包括这里的language API。你需要同时包含Google AJAX APIs的script标签并且调用google.load(&#8220;language&#8221;,&#8221;1&#8243;);。</p>
<pre class="prettyprint">&lt;script type="text/javascript" src="http://www.google.com/jsapi" mce_src="http://www.google.com/jsapi"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

  google.load("language", "1");

&lt;/script&gt;</pre>
<p>第一个script标签加载了google.load函数，这个函数允许你加载特定的 Google API。google.load(&#8220;language&#8221;,&#8221;1&#8243;)加载了Language API的第一版。当前，AJAX Language API的版本为1，但是不久后新版本将可以使用。参考下面的<a href="http://code.google.com/apis/ajaxlanguage/documentation/#Versioning">版本讨论</a>来获得更多信息。</p>
<h3>API 更新</h3>
<p>google.load函数的第二个参数实际上是你所使用的AJAX Language API的版本。当前，AJAX Language API的版本为1，但是不久后新版本将可以使用。</p>
<p>如果以后我们对API进行重要更新，我们将改变版本号，并且在<a href="http://code.google.com/">Google Code</a>和<a href="http://googleajaxsearchapi.blogspot.com/">AJAX APIS 讨论</a>中发布通知。当该事件发生后，我们预期会在至少一个月的时间内继续支持所有版本来使你有足够的时间来迁移你的代码。</p>
<p>AJAX Language API团队对于最近日较的Bug修复和平台优化进行定期更新。这些Bug修复应当仅提高表现和修复Bug，但是我们有可能不小心破坏某些API用户、请使用<a href="http://googleajaxsearchapi.blogspot.com/">AJAX APIs 讨论组</a>来报告这样的问题。</p>
<h2>实例</h2>
<h3>语言翻译</h3>
<p>本案例展示了一个简单的对一个JavaScript字符串变量进行翻译的过程。</p>
<pre class="prettyprint">
google.language.translate("Hello world", "en", "es", function(result) {

  if (!result.error) {

    var container = document.getElementById("translation");

    container.innerHTML = result.translation;

  }

});</pre>
<p><a href="http://code.google.com/apis/ajaxlanguage/documentation/translate.html">查看案例（translate.html）</a></p>
<h3>语言检测</h3>
<p>这个案例展示了对于一个JavaScript字符串的语言检测。将返回语言代码。</p>
<pre class="prettyprint">
var text = "¿Dónde está el baño?";

google.language.detect(text, function(result) {

  if (!result.error) {

    var language = 'unknown';

    for (l in google.language.Languages) {

      if (google.language.Languages[l] == result.language) {

        language = l;

        break;

      }

    }

    var container = document.getElementById("detection");

    container.innerHTML = text + " is: <strong>" + language + "</strong>";

  }

});</pre>
<p><a href="http://code.google.com/apis/ajaxlanguage/documentation/detection.html">查看案例 (detection.html)</a></p>
<h3>翻译时源检测</h3>
<p>如下的案例类似于基本的翻译案例，但是它展示了如何在不知道源语言时对文本进行翻译。通过传入一个空字符串来表示未知的源语言，系统将在一次调用中自动检测和翻译。</p>
<pre class="prettyprint">
google.language.translate("Hello world", "", "es", function(result) {

  if (!result.error) {

    var container = document.getElementById("translation");

    container.innerHTML = result.translation;

  }

});</pre>
<h2>更多案例</h2>
<p>这里有进行交互作用的两个附加案例。第一个案例对预输入的文本字符串进行语言检测，同时也允许输入其他的文本。它同时也显示信任和可靠因数（confidence and reliability factors-译者注）。</p>
<p><a href="http://www.google.com/uds/samples/language/detect.html">查看案例(detect.html)</a></p>
<p>第二个附加案例进行翻译。同时他也允许与上述类似的交互作用。</p>
<p><a href="http://www.google.com/uds/samples/language/translate.html">查看案例(translate.html)</a></p>
<h2>API细节</h2>
<h3>支持的语言</h3>
<p>Google AJAX Language API现在支持下列语言。该技术正在不断的提高，同时我们的团队也在努力的扩展这个列表，因此请经常回来看看。你也可以访问<a href="http://translate.google.com/">Google Translate</a>来查看最近更新的列表。</p>
<ul>
<li>Arabic （阿拉伯语）</li>
<li>Chinese (Simplified and Traditional) （中文简体）</li>
<li>Dutch （荷兰语）</li>
<li>English （英语）</li>
<li>French （法语）</li>
<li>German （德语）</li>
<li>Greek （希腊语）</li>
<li>Italian （意大利语）</li>
<li>Japanese （日语）</li>
<li>Korean （韩语）</li>
<li>Portuguese （葡萄牙语）</li>
<li>Russian （俄语）</li>
<li>Spanish（西班牙语）</li>
</ul>
<h3>支持的语言翻译对</h3>
<p>Google AJAX Language API现在支持下列语言翻译对。该技术正在不断的提高，同时我们的团队也在努力的扩展这个列表，因此请经常回来看看。你也可以访问<a href="http://translate.google.com/">Google Translate</a>来查看最近更新的列表。</p>
<ul>
<li>Arabic to English （阿拉伯语到英语）</li>
<li>Chinese to English （中文到英语）</li>
<li>Chinese (Simplified to Traditional) （简体中文到繁体中文）</li>
<li>Chinese (Traditional to Simplified) （繁体中文到简体中文）</li>
<li>Dutch to English （荷兰语到英语）</li>
<li>English to Arabic （英语到阿拉伯语）</li>
<li>English to Chinese (Simplified) （英语到简体中文）</li>
<li>English to Chinese (Traditional) （英语到繁体中文）</li>
<li>English to Dutch （英语到荷兰语）</li>
<li>English to French （英语到法语）</li>
<li>English to German （英语到德语）</li>
<li>English to Greek （英语到希腊语）</li>
<li>English to Italian （英语到意大利语）</li>
<li>English to Japanese （英语到日语）</li>
<li>English to Korean （英语到韩语）</li>
<li>English to Portuguese （英语到葡萄牙语）</li>
<li>English to Russian （英语到俄语）</li>
<li>English to Spanish （英语到西班牙语）</li>
<li>French to English （法语到英语）</li>
<li>French to German （法语到德语）</li>
<li>German to English （德语到英语）</li>
<li>German to French （德语到法语）</li>
<li>Greek to English （希腊语到英语）</li>
<li>Italian to English （意大利语到英语）</li>
<li>Japanese to English （日语到英语）</li>
<li>Korean to English （韩语到英语）</li>
<li>Portuguese to English （葡萄牙语到英语）</li>
<li>Russian to English （俄语到英语）</li>
<li>Spanish to English（西班牙语到英语）</li>
</ul>
<h2>问题解决</h2>
<p>如果在你的代码中遇到了问题：</p>
<ul>
<li>检查代码。请牢记JavaScript是对大小写敏感的语言。</li>
<li>使用JavaScript调试器、在Firefox中，你可以使用JavaScript控制台或者FireBug扩展。在IE中，你可以使用Microsoft Script Debugger。</li>
<li>在AJAX APIs讨论组中搜索。如果你找不到回答你问题的帖子，那么可以在讨论组中发布你的问题，并且包含指向你出问题的页面的链接。</li>
</ul>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference" title="[译文]Google AJAX Language API对象参考">[译文]Google AJAX Language API对象参考</a></li><li><a href="http://www.hanguofeng.cn/archives/security/sql-injection-attack" title="SQL注入攻击-来自微软安全博客的建议">SQL注入攻击-来自微软安全博客的建议</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/google-language-for-wordpress" title="Google Language for WordPress">Google Language for WordPress</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译文]防止CSRF攻击</title>
		<link>http://www.hanguofeng.cn/archives/security/preventing-csrf?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=preventing-csrf</link>
		<comments>http://www.hanguofeng.cn/archives/security/preventing-csrf#comments</comments>
		<pubDate>Thu, 07 Feb 2008 17:31:09 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[网络安全]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/archives/%e7%bd%91%e7%bb%9c%e5%ae%89%e5%85%a8/preventing-csrf</guid>
		<description><![CDATA[说明：

译言链接：http://www.yeeyan.com/articles/view/hanguofeng/3994

原文链接：http://www.playhack.net/view.php?id=31]]></description>
			<content:encoded><![CDATA[<p>说明：</p>
<p>译言链接：<a href="http://www.yeeyan.com/articles/view/hanguofeng/3994">http://www.yeeyan.com/articles/view/hanguofeng/3994</a><br />
原文链接：<a href="http://www.playhack.net/view.php?id=31">http://www.playhack.net/view.php?id=31</a></p>
<p><span id="more-6"></span></p>
<h2>概览：</h2>
<p>1. Hello World<br />
2. 介绍<br />
3. 关于认证技术<br />
3.1 Cookies Hashing<br />
3.2 HTTP来路<br />
3.3 验证码<br />
4. 一次性令牌<br />
5. 最后的话</p>
<h2>1.Hello World</h2>
<p>欢迎来到崭新的Playhack.net的新季度开题项目报告。我非常高兴您能够再次回来让我们的c001项目重现。</p>
<p>希望您能喜欢这个新的短篇论文，我邀请你浏览位于http://www.playhack.net的全部新项目。</p>
<p>开始：几乎没有什么，只是一点香烟!:</p>
<p>呐喊：我向我的playhack m8s null,omni,god and emdel,ofc o str0ke大声呐喊!NEX 回来了。</p>
<h2>2.介绍</h2>
<p>我对跨站请求伪造（Cross Site Request Forgery，即CSRF）技术有一定研究，但是对网站开发者应当采取的措施研究不深。这些日子在编写一个对用户和管理员（这些人对他们的任务并不明晰:P）有高度安全要求的分布式网站程序时，我被这个话题深刻的纠缠了。</p>
<p>针对这种情况，我必须考虑程序最终可能受到的各个方面的可能的攻击威胁。</p>
<p>给我最多麻烦的就是Session欺骗（或者CSRF，你可以按照自己喜欢的方式称呼），因为这种攻击是完全以用户的身份，因此并没有百分百的可能性来防止它。</p>
<p>如果你对我刚才说所的Session欺骗并不太了解，那么你可以阅读：http://www.playhack.net/view.php?id=30</p>
<h2>3.可行措施</h2>
<p>Ok，从这里开始，我必须假定你对Session欺骗攻击的实施方法已经深刻领会了:P</p>
<p>让我们开始新的继续。</p>
<p>考虑到一个已经登录到网站的受信用户可以完成一些重要的或者私密的操作，攻击者尝试记性一个可能的登录攻击（但是大多数情况下是不可行的）并且得到已经登录用户的Session来实现其巧妙的行为。</p>
<p>为了劫持用户的Seession，入侵者精心构造一个适当的网页，在这个网页中包含了隐藏的JavaScript函数来重新创造一个原始操作表单，但是攻击者却修改了一些表单值，然后攻击者让受攻击者访问该页面，此时页面加载过程会提交上述表单到一个远程页面，以隐秘地完成一个请求（此时受攻击者并不知道），他们用这种方法利用了用户的受信身份。</p>
<p>这种方式简单解释了Session欺骗攻击是如何工作的，但是一个重要的问题是，“我如何避免我的用户成为这种攻击的受害者？”</p>
<p>现在，你可能想到如下的几种方法：</p>
<p>检查Cookies凭据<br />
检查HTTP请求来路<br />
使用验证码<br />
但是经过一些尝试，你会发现这些方法不是我们应当采取的最合适的解决方式，让我们一个个的来看为什么。</p>
<h3>3.1 Cookies Hashing</h3>
<p>第一个方案可能是解决这个问题的最简单和快捷的方案了，因为攻击者不能够获得被攻击者的Cookies内容，也就不能够构造相应的表单。</p>
<p>这个问题的实现方法与下面的类似。在某些登录页面我们根据当前的会话创建Cookies：</p>
<p>&lt;!&#8211; login.php &#8211;&gt;<br />
&lt;?php<br />
// Cookie value<br />
$value = &#8220;Something from Somewhere&#8221;;<br />
// Create a cookie which expires in one hour<br />
setcookie(&#8220;cookie&#8221;, $value, time()+3600);<br />
?&gt;<br />
&lt;!&#8211; EOF &#8211;&gt;</p>
<p>在这里，我们在Cookies中使用了散列来使得这个表单可被认证。</p>
<p>&lt;!&#8211; form.php &#8211;&gt;<br />
&lt;?php<br />
// Hash the cookie<br />
$hash = md5($_COOKIE['cookie']);<br />
?&gt;<br />
&lt;form method=&#8221;POST&#8221; action=&#8221;resolve.php&#8221;&gt;<br />
&lt;input type=&#8221;text&#8221; name=&#8221;first_name&#8221;&gt;<br />
&lt;input type=&#8221;text&#8221; name=&#8221;last_name&#8221;&gt;<br />
&lt;input type=&#8221;hidden&#8221; name=&#8221;check&#8221; value=&#8221;&lt;?=$hash;?&gt;&#8221;&gt;<br />
&lt;input type=&#8221;submit&#8221; name=&#8221;submit&#8221; value=&#8221;Submit&#8221;&gt;<br />
&lt;/form&gt;<br />
&lt;!&#8211; EOF &#8211;&gt;</p>
<p>此时，后台的动态网页部分可以进行如下操作：</p>
<p>     &lt;!&#8211; resolve.php &#8211;&gt;<br />
      &lt;?php<br />
      // Check if the &#8220;check&#8221; var exists<br />
      if(isset($_POST['check'])) {<br />
           $hash = md5($_COOKIE['cookie']);<br />
           // Check if the values coincide<br />
           if($_POST['check'] == $hash) {<br />
                do_something();<br />
           } else {<br />
                echo &#8220;Malicious Request!&#8221;;<br />
           }<br />
      } else {<br />
           echo &#8220;Malicious Request!&#8221;;<br />
      }<br />
      ?&gt;<br />
      &lt;!&#8211; EOF &#8211;&gt;</p>
<p>事实上，如果我们不考虑用户的Cookies很容易由于网站中存在XSS漏洞而被偷窃（我们已经知道这样的事情并不少见）这一事实，这是一个很好的应对对CSRF的解决方案。如果我们为用户的每一个表单请求中都加入随机的Cookies，那么这种方法会变得更加安全，但是这并不是十分合适。</p>
<h3>3.2 HTTP来路</h3>
<p>检测访问来路是否可信的最简单方法是，获得HTTP请求中的来路信息（即名为Referer的HTTP头—译者注）并且检查它来自站内还是来自一个远程的恶意页面：这是一个很好的解决方法，但是由于可以对服务器获得的请求来路进行欺骗以使得他们看起来合法，这种方法不能够有效防止攻击。</p>
<p>让我们来看看为什么这并不是一个合适的方法。</p>
<p>下面的代码展示了HTTP Referer实现方法的一个例子：</p>
<p>     &lt;!&#8211; check.php &#8211;&gt;<br />
      if(eregi(&#8220;www.playhack.net&#8221;, $_SERVER['HTTP_REFERER'])) {<br />
           do_something();<br />
      } else {<br />
           echo &#8220;Malicious Request!&#8221;;<br />
      }<br />
      &lt;!&#8211; EOF &#8211;&gt;</p>
<p>这个检测则会轻易的忽略掉来自某个攻击者伪造的HTTP Referer欺骗，攻击者可以使用如下代码：</p>
<p>header(&#8220;Referer: www.playhack.net&#8221;);</p>
<p>或者其他在恶意脚本中伪造HTTP头并发送的方法。</p>
<p>由于HTTP Referer是由客户端浏览器发送的，而不是由服务器控制的，因此你不应当将该变量作为一个信任源。</p>
<h3>3.3 验证码</h3>
<p>另外一个解决这类问题的思路则是在用户提交的每一个表单中使用一个随机验证码，让用户在文本框中填写图片上的随机字符串，并且在提交表单后对其进行检测。</p>
<p>这个方法曾经在之前被人们放弃，这是由于验证码图片的使用涉及了一个被称为MHTML的Bug，可能在某些版本的微软IE中受影响。</p>
<p>你可以在Secunia的站点上获得关于此缺陷的详细信息：http://secunia.com/advisories/19738/ 。</p>
<p>这里是Secunia关于此Bug解释的概述：</p>
<p>“此缺陷是由于处理“mhtml:”的URL处理器重定向引起的。它可以被用来利用从另外一个网站访问当前的文档”</p>
<p>在同一个页面你会找到来自Secunia工作人员的网站测试方法。</p>
<p>事实上，我们知道，这个Bug已经被微软放出的Windows XP和Windows Vista及其浏览器IE6.0的修复包所解决了。</p>
<p>即使他的确出现了安全问题，这么长时间也会有其他的可靠方案出现。</p>
<h2>4.一次性令牌</h2>
<p> 现在让我们来看经过研究，我希望介绍的最后一种解决方案：在使用这些不可靠的技术后，我尝试做一些不同然而却是更有效的方法。</p>
<p>为了防止Web表单受到Session欺骗（CSRF）的攻击，我决定检测可能被伪装或伪造的每一个项目。因此我需要来创造一次性令牌，来使得在任何情况下都不能够被猜测或者伪装，这些一次性令牌在完成他们的工作后将被销毁。</p>
<p>让我们从令牌值的生成开始：</p>
<p>     &lt;!&#8211; start function &#8211;&gt;<br />
     &lt;?php<br />
     function gen_token() {<br />
          // Generate the md5 hash of a randomized uniq id<br />
          $hash = md5(uniqid(rand(), true));<br />
          // Select a random number between 1 and 24 (32-8)<br />
          $n = rand(1, 24);<br />
          // Generate the token retrieving a part of the hash starting from<br />
          // the random N number with 8 of lenght<br />
          $token = substr($hash, $n, 8);<br />
          return $token;<br />
     }<br />
     ?&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p> PHP函数uniqid()允许web开发者根据当前的时间（毫秒数）获得一个唯一的ID，这个唯一ID有利于生成一个不重复的数值。</p>
<p>我们检索相应ID值的MD5散列，而后我们从该散列中以一个小于24的数字为开始位置，选取8位字母、</p>
<p>返回的$token变量将检索一个8位长的随机令牌。</p>
<p>现在让我们生成一个Session令牌，在稍后的检查中我们会用到它。</p>
<p>     &lt;!&#8211; start function &#8211;&gt;<br />
     &lt;?php<br />
     function gen_stoken() {<br />
          // Call the function to generate the token<br />
          $token = gen_token();<br />
          // Destroy any eventually Session Token variable<br />
          destroy_stoken();<br />
          // Create the Session Token variable<br />
          session_register(STOKEN_NAME);<br />
          $_SESSION[STOKEN_NAME] = $token;<br />
     }<br />
     ?&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p> 在这个函数中我们调用gen_token()函数，并且使用返回的令牌将其值复制到一个新的$_SESSION变量。</p>
<p>现在让我们来看启动完整机制中为我们的表单生成隐藏输入域的函数：</p>
<p>     &lt;!&#8211; start function &#8211;&gt;<br />
     &lt;?php<br />
     function gen_input() {<br />
          // Call the function to generate the Session Token variable<br />
          gen_stoken();<br />
          // Generate the form input code<br />
          echo &#8220;&lt;input type=\&#8221;hidden\&#8221; name=\&#8221;" . FTOKEN_NAME . &#8220;\&#8221;<br />
               value=\&#8221;" . $_SESSION[STOKEN_NAME] . &#8220;\&#8221;&gt; &#8220;;<br />
     }<br />
     ?&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p>我们可以看到，这个函数调用了gen_stoken()函数并且生成在WEB表单中包含隐藏域的HTML代码。</p>
<p>接下来让我们来看实现对隐藏域中提交的Session令牌的检测的函数：</p>
<p>     &lt;!&#8211; start function &#8211;&gt;<br />
     &lt;?php<br />
     function token_check() {<br />
          // Check if the Session Token exists<br />
          if(is_stoken()) {<br />
               // Check if the request has been sent<br />
               if(isset($_REQUEST[FTOKEN_NAME])) {<br />
                    // If the Form Token is different from Session Token<br />
                    // it&#8217;s a malicious request<br />
                    if($_REQUEST[FTOKEN_NAME] != $_SESSION[STOKEN_NAME]) {<br />
                         gen_error(1);<br />
                         destroy_stoken();<br />
                         exit();<br />
                    } else {<br />
                         destroy_stoken();<br />
                    }<br />
               // If it isn&#8217;t then it&#8217;s a malicious request<br />
               } else {<br />
                    gen_error(2);<br />
                    destroy_stoken();<br />
                    exit();<br />
               }<br />
          // If it isn&#8217;t then it&#8217;s a malicious request<br />
          } else {<br />
               gen_error(3);<br />
               destroy_stoken();<br />
               exit();<br />
          }<br />
     }<br />
     ?&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p>这个函数检测了$_SESSION[STOKEN_NAME]和$_REQUEST[FTOKEN_NAME]的存在性（我使用了$_REQUEST方法来使得GET和POST两种方式提交的表单变量均能够被接受），而后检测他们的值是否相同，因此判断当前表单提交是否是经过认证授权的。</p>
<p>这个函数的重点在于：在每次检测步骤结束后，令牌都会被销毁，并且仅仅在下一次表单页面时才会重新生成。</p>
<p>这些函数的使用方法非常简单，我们只需要加入一些PHP代码结构。</p>
<p>下面是Web表单：</p>
<p>     &lt;!&#8211; form.php &#8211;&gt;<br />
     &lt;?php<br />
          session_start();<br />
          include(&#8220;functions.php&#8221;);<br />
     ?&gt;<br />
     &lt;form method=&#8221;POST&#8221; action=&#8221;resolve.php&#8221;&gt;<br />
          &lt;input type=&#8221;text&#8221; name=&#8221;first_name&#8221;&gt;<br />
          &lt;input type=&#8221;text&#8221; name=&#8221;last_name&#8221;&gt;<br />
          &lt;!&#8211; Call the function to generate the hidden input &#8211;&gt;<br />
          &lt;? gen_input(); ?&gt;<br />
          &lt;input type=&#8221;submit&#8221; name=&#8221;submit&#8221; value=&#8221;Submit&#8221;&gt;<br />
     &lt;/FORM&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p> 下面是解决的脚本代码：</p>
<p>     &lt;!&#8211; resolve.php &#8211;&gt;<br />
     &lt;?php<br />
          session_start();<br />
          include(&#8220;functions.php&#8221;);<br />
          <br />
          // Call the function to make the check<br />
          token_check();<br />
          <br />
          // Your code<br />
          &#8230;<br />
     ?&gt;<br />
     &lt;!&#8211; EOF &#8211;&gt;</p>
<p>你可以看到，实现这样一个检测是十分简单的，但是它可以避免你的用户表单被攻击者劫持，以避免数据被非法授权。</p>
<h2>5.结论</h2>
<p>让我们对这篇简短的论文做一个结论，你的Web应用程序没有百分百的安全，但是你可以开始避免绝大多数普通的攻击技术。</p>
<p>我希望您关注的另一个要点是，Web开发者<strong>不应当</strong>忽视一般的程序错误（例如XSS 浏览器漏洞等等），不将这些考虑为对您的用户的潜在威胁是一个巨大的错误：你应该永远记得它们将影响程序的信任性、安全性和互操作性。</p>
<p>Cya!</p>
<p>nexus</p>
<p>（前面的PHP代码是从Seride项目中参考的，该项目地址为：http://projects.playhack.net/project.php?id=3）</p>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/security/sql-injection-attack" title="SQL注入攻击-来自微软安全博客的建议">SQL注入攻击-来自微软安全博客的建议</a></li><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference" title="[译文]Google AJAX Language API对象参考">[译文]Google AJAX Language API对象参考</a></li><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-developers-guide" title="[译文]Google AJAX Language API开发者参考">[译文]Google AJAX Language API开发者参考</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/security/preventing-csrf/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>[译文]WordPress插件API手册</title>
		<link>http://www.hanguofeng.cn/archives/web-server/wordpress-plugin-api?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=wordpress-plugin-api</link>
		<comments>http://www.hanguofeng.cn/archives/web-server/wordpress-plugin-api#comments</comments>
		<pubDate>Tue, 01 Jan 2008 09:58:29 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web服务器端技术]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/archives/web/wordpress%e6%8f%92%e4%bb%b6api%e6%89%8b%e5%86%8c</guid>
		<description><![CDATA[说明： 译言链接：http://www.yeeyan.com/articles/view/hanguofeng/3805 原文链接：http://codex.wordpress.org/Plugin_API 概述 本文档介绍了在WordPress中对插件开发者有用的API（Application Programming Interface，应用编程接口）的使用方法。 本文假设你已经阅读了简要介绍插件开发方法的文章：Writing a Plugin，本文主要就介绍Hook API，比如Filters、Action，这使得WordPress可以加载你的插件。 注意：本文所提到的信息针对WordPress1.2及以上版本，在1.2版之前，这些插件被称为“hacks”，他们主要是通过修改WordPress本身的源码来实现的。 译者注：在本文中，为了便于对原文的准确翻译，一些程序设计的专有词汇没有进行翻译，你可以阅读如下单词表来参考： API，应用程序编程接口。 Hook，钩子，意为在WordPress的处理中加入你自己的处理。 Filter，过滤器。 Action，动作。 Hooks，Actions和Filters Hook是WordPress提供的，允许你的插件“勾入”WordPress的程序，或者说，可以在特定时候执行你插件中的函数，从而使得你的插件执行。这里提供了两种hook： Action：Action（动作）是WordPress程序核心在程序执行的特殊点（特定事件发生）加载的。使用Action API，你的插件可以在这些特殊点执行一个或者多个在插件中编写的PHP函数。 Filter：Filter（过滤器）是WordPress加载的，当文本被存入数据库或发送到浏览器之前，Filter可用来对其进行多种类型的处理。使用Filter，你的插件可以使用定义在其中的PHP函数来对文本进行多种处理。 某些时候，你可以用Action或者Filter实现同样的功能。举例来说，如果你编写了一个插件用来修改博客日志的文本，你可以加入一个Action函数到publist_post的事件（这样日志就会在存入数据库时被修改），也可以加入一个Fliter函数到the_content（这时日志内会在显示到浏览器之前被修改）。 Actions（动作） Action（动作）在WordPress进行某些特殊事件处理时被触发，例如发布日志，修改主题，或者在管理员面板显示页面。你的插件可以通过执行PHP函数来发挥作用，他们可以用来做如下事情： 修改数据库中的数据 发送Email消息 修改在浏览器中显示的信息（包括管理员看到的和访问者看到的） 实施Action的基本步骤是： 在你的插件中编写当事件发生时执行的PHP函数。 通过执行add_action函数将这些操作Hook（勾入）到WordPress中。 将你的PHP函数放入插件文件，并且将其激活。 编写Action函数 在插件中创建Action的第一步是在插件中编写一个实现Action功能的PHP函数并且将其放入你的插件文件（插件文件必须放置在wp-content/plugins目录）中。比如，如果你希望当发表一篇日志后，发送Email通知给你的朋友，那么你可以定义如下函数： function email_friends($post_ID)  {     $friends = 'bob@example.org,susie@example.org';     mail($friends, "sally's blog updated",       'I just put something on my blog: http://blog.example.com'); [...]]]></description>
			<content:encoded><![CDATA[<p>说明：</p>
<p>译言链接：<a href="http://www.yeeyan.com/articles/view/hanguofeng/3805">http://www.yeeyan.com/articles/view/hanguofeng/3805</a></p>
<p>原文链接：<a href="http://codex.wordpress.org/Plugin_API">http://codex.wordpress.org/Plugin_API</a></p>
<p><span id="more-4"></span></p>
<h2>概述</h2>
<p>本文档介绍了在WordPress中对插件开发者有用的API（Application Programming Interface，应用编程接口）的使用方法。</p>
<p>本文假设你已经阅读了简要介绍插件开发方法的文章：<a href="http://codex.wordpress.org/Writing_a_Plugin" title="Writing a Plugin"><strong><font color="#003366">Writing a Plugin</font></strong></a>，本文主要就介绍Hook API，比如Filters、Action，这使得WordPress可以加载你的插件。</p>
<p>注意：本文所提到的信息针对WordPress1.2及以上版本，在1.2版之前，这些插件被称为“hacks”，他们主要是通过修改WordPress本身的源码来实现的。</p>
<p>译者注：在本文中，为了便于对原文的准确翻译，一些程序设计的专有词汇没有进行翻译，你可以阅读如下单词表来参考：</p>
<ul>
<li>API，应用程序编程接口。</li>
<li>Hook，钩子，意为在WordPress的处理中加入你自己的处理。</li>
<li>Filter，过滤器。</li>
<li>Action，动作。</li>
</ul>
<h2>Hooks，Actions和Filters</h2>
<p>Hook是WordPress提供的，允许你的插件“勾入”WordPress的程序，或者说，可以在特定时候执行你插件中的函数，从而使得你的插件执行。这里提供了两种hook：</p>
<ol>
<li>Action：Action（动作）是WordPress程序核心在程序执行的特殊点（特定事件发生）加载的。使用Action API，你的插件可以在这些特殊点执行一个或者多个在插件中编写的PHP函数。</li>
<li>Filter：Filter（过滤器）是WordPress加载的，当文本被存入数据库或发送到浏览器之前，Filter可用来对其进行多种类型的处理。使用Filter，你的插件可以使用定义在其中的PHP函数来对文本进行多种处理。</li>
</ol>
<p>某些时候，你可以用Action或者Filter实现同样的功能。举例来说，如果你编写了一个插件用来修改博客日志的文本，你可以加入一个Action函数到publist_post的事件（这样日志就会在存入数据库时被修改），也可以加入一个Fliter函数到the_content（这时日志内会在显示到浏览器之前被修改）。</p>
<h2>Actions（动作）</h2>
<p>Action（动作）在WordPress进行某些特殊事件处理时被触发，例如发布日志，修改主题，或者在管理员面板显示页面。你的插件可以通过执行PHP函数来发挥作用，他们可以用来做如下事情：</p>
<ul>
<li>修改数据库中的数据</li>
<li>发送Email消息</li>
<li>修改在浏览器中显示的信息（包括管理员看到的和访问者看到的）</li>
</ul>
<p>实施Action的基本步骤是：</p>
<ol>
<li>在你的插件中编写当事件发生时执行的PHP函数。</li>
<li>通过执行add_action函数将这些操作Hook（勾入）到WordPress中。</li>
<li>将你的PHP函数放入插件文件，并且将其激活。</li>
</ol>
<h3>编写Action函数</h3>
<p>在插件中创建Action的第一步是在插件中编写一个实现Action功能的PHP函数并且将其放入你的插件文件（插件文件必须放置在wp-content/plugins目录）中。比如，如果你希望当发表一篇日志后，发送Email通知给你的朋友，那么你可以定义如下函数：</p>
<p><code>function email_friends($post_ID)  {<br />
    $friends = 'bob@example.org,susie@example.org';<br />
    mail($friends, "sally's blog updated",<br />
      'I just put something on my blog: http://blog.example.com');<br />
    return $post_ID;<br />
}<br />
</code></p>
<p>在大多数Action中，你的函数应该接受一个参数（通常是日志或者帖子的编号，这取决于你要进行的操作）。某些Action可能有多余一个参数&#8211;你可以通过查看Action的文档或者WordPress源代码来获得更多信息。除函数参数外，你还可以访问WordPress的全局变量以及执行WordPress中定义的其他函数（或者在你的插件文件中定义的函数）。</p>
<p><strong>注意</strong>：切记其他插件或者WordPress核心可能已经使用了你希望使用的函数名称，你可以浏览<a href="http://www.yeeyan.com/Writing_a_Plugin#Avoiding_Function_Name_Collisions" title="Writing a Plugin"><strong><font color="#003366">Avoiding Function Name Collisions</font></strong></a>（避免函数名称冲突&#8211;译者注）来获得更多信息。</p>
<h3>Hook（勾入）到WordPress</h3>
<p>完成你的函数的编写后，下一步就是将其hook（勾入）或者说注册到WordPress中，你可以通过执行全局空间中的add_action()函数来实现，如：</p>
<p><code>add_action ( 'hook_name', 'your_function_name', [priority], [accepted_args] );</code>此处</p>
<ul>
<li>hook_name参数是WordPress提供的Action Hook（动作钩子）名称，这决定了你的函数应当和哪个事件结合。</li>
<li>your_function_name参数是你希望在特定事件（即hook_name参数指定的事件）后执行的函数名称。该函数可以是标准的PHP函数，在WordPress核心中定义的函数或者你自己在插件文件中定义的函数（如刚才我们编写的emai_friends函数）。</li>
<li>priority参数是一个可选的整型参数，他用来指明在结合特定事件的多个函数中，当前函数被执行的顺序（默认为10）。该参数指定的更小的数字会被更早的执行，priority参数相同的函数会依照他们被加入Action的顺序来执行。</li>
<li>accepted_args参数是一个可选的整型参数，他定义了你的函数中可以接收多少个参数（默认为1）。该参数是非常有用的，因为某些Hook可以向你的函数中传入多个参数。该参数在1.5.1版本中被新加入。</li>
</ul>
<p>在前面的例子中，我们可以在插件文件中加入如下代码：</p>
<p><code>add_action('publish_post', 'email_friends');</code>同样的，你也可以在Action Hook中移除Action，你可以参考<a href="#Removing_Actions_and_Filters"><strong><font color="#003366">Remove Actions</font></strong></a>来获得更多详情。</p>
<h3>安装和激活</h3>
<p>让你的Action Hook开始工作的最后一步是安装插件文件和激活插件。你必须将你编写的PHP函数和add_action函数存入同一个PHP文件，该PHP文件必须被安装在wp-content/plugins目录，当该文件安装完毕，你需要浏览WordPress的管理面板，并且激活你的插件，你可以参考<a href="http://codex.wordpress.org/Managing_Plugins" title="Managing Plugins"><strong><font color="#003366">Managing Plugins</font></strong></a>文章来获得更多信息。</p>
<h3>当前可用的Action Hook</h3>
<p>请浏览<a href="http://codex.wordpress.org/Plugin_API/Action_Reference" title="Plugin API/Action Reference"><strong><font color="#003366">Plugin API/Action Reference</font></strong></a>（插件API/Action参考&#8211;译者注）来获得一份当前版本的WordPress中可用的Action Hook。</p>
<h2>Filters（过滤器）</h2>
<p>Filters（过滤器）是WordPress在执行中的特定点传递数据的函数，他发生在对数据进行操作（如将其加入数据库或发送到浏览器）之前。Filter建立在数据库到浏览器之间的处理（当WordPress生成页面时），同时也建立在浏览器到数据库之间的处理（当WordPress新增日志或者评论到数据库时）；多数WordPress中的输入输出都通过了至少一个filter。WordPress默认已经实现了一些过滤操作，你的插件也可以加入你自己的过滤操作。</p>
<p>将你的filter加入WordPress中的基本步骤如下：</p>
<ol>
<li>编写用于过滤数据的PHP函数。</li>
<li>通过执行add_filter函数将filter Hook（勾入）到WordPress。</li>
<li>将你的PHP函数放入插件文件，并且将其激活。</li>
</ol>
<h3>编写Filter（过滤器）函数</h3>
<p>Filter（过滤器）函数获得未经修改的数据，并返回修改后的数据（或者在某些情况下，返回null值来标识数据应当被删除或忽略）。如果你的filter不修改数据，那么应当返回原始数据，这样，如果必要，其余的插件可以继续修改数据。</p>
<p>因此，在你的插件中创建filter的第一步是编写一个PHP函数来进行过滤处理，并且将其放在你的插件文件（插件文件必须放置在wp-content/plugins目录）当中。例如，如果你希望确保你的帖子和评论中不包含脏话，你可以定义一个存放禁止词汇的全局变量，然后编写如下的PHP函数：</p>
<p><code>function filter_profanity($content) {<br />
    global $profanities;<br />
    foreach($profanities as $profanity) {<br />
        $content=str_ireplace($profanity,'{censored}',$content);<br />
    }<br />
    return $content;<br />
}<br />
</code><strong>注意</strong>：切记其他插件或者WordPress核心可能已经使用了你希望使用的函数名称，你可以浏览<a href="#Avoiding_Function_Name_Collisions" title="Writing a Plugin"><strong><font color="#003366">Avoiding Function Name Collisions</font></strong></a>（避免函数名称冲突&#8211;译者注）来获得更多信息。</p>
<h3>Hook（勾入）到WordPress</h3>
<p>完成你的函数的编写后，下一步就是将其hook（勾入）或者说注册到WordPress中，你可以通过执行全局空间中的add_filter()函数来实现，如：</p>
<p><code>add_filter('hook_name', 'your_filter', [priority], [accepted_args]);</code>此处：</p>
<ul>
<li>hook_name参数是WordPress提供的Filter Hook（过滤器钩子）名称，这决定了你的函数在何时发挥作用。</li>
<li>your_filter参数是你希望用来过滤的函数的名称。该函数可以是标准的PHP函数，在WordPress核心中定义的函数或者你自己在插件文件中定义的函数。</li>
<li>priority参数是一个可选的整型参数，他用来指明在结合特定事件的多个函数中，当前函数被执行的顺序（默认为10）。该参数指定的更小的数字会被更早的执行，priority参数相同的函数会依照他们被加入Action的顺序来执行。</li>
<li>accepted_args参数是一个可选的整型参数，他定义了你的函数中可以接收多少个参数（默认为1）。该参数是非常有用的，因为某些Hook可以向你的函数中传入多个参数。该参数在1.5.1版本中被新加入。</li>
</ul>
<p>在前面的例子中，我们可以将下面的代码放入你的插件文件中的主要执行部分，来通知WordPress对评论中的脏话进行过滤处理：</p>
<p>add_filter(&#8216;comment_text&#8217;,'filter_profanity&#8217;);</p>
<p>你也可以使用WordPress函数remove_filter()来移除filter hook中的filter。你可以参考<a href="#Removing_Actions_and_Filters"><strong><font color="#003366">Removing Actions and Filters</font></strong></a>文章。</p>
<h3>安装和激活</h3>
<p>让你的Filter Hook开始工作的最后一步是安装插件文件和激活插件。你必须将你编写的PHP函数和add_filter函数存入同一个PHP文件，该PHP文件必须被安装在wp-content/plugins目录，当该文件安装完毕，你需要浏览WordPress的管理面板，并且激活你的插件，你可以参考<a href="http://codex.wordpress.org/Managing_Plugins" title="Managing Plugins"><strong><font color="#003366">Managing Plugins</font></strong></a>文章来获得更多信息。</p>
<h3>当前可用的Filter Hook</h3>
<p>请浏览<a href="http://codex.wordpress.org/Plugin_API/Filter_Reference" title="Plugin API/Filter Reference"><strong><font color="#003366">Plugin API/Filter Reference</font></strong></a> （插件API/Filter参考&#8211;译者注）来获得一份当前版本的WordPress中可用的Filter Hook。 </p>
<h2>删除Action和Filter</h2>
<p>在某些情况下，你会发现你希望你的插件屏蔽WordPress内建或者其他插件加入的Action或Filter。你可以通过执行<code>remove_filter('filter_hook','filter_function')函数或者remove_action('action_hook','action_function')函数来实现。</code></p>
<p>举例来说，remove_action(&#8216;publish_post&#8217;,'generic_ping&#8217;);会使得你在发表新日志时不发送日志引用（ping）。</p>
<p>注意如果某个hook在注册时使用了除默认值10意外的priority参数，则你必须修改在remove_action()函数中的priority参数。同时也请注意，通常来讲除非你知道这样做的原因和后果，你不应当移除任何东西&#8211;请检查WordPress或者其他插件的源代码来保证这一点。</p>
<h2>默认应用的Filter和Action</h2>
<p>找出WordPress默认启用的filter和Action的最可靠方法是在WordPress核心文件中搜索 add_filter和add_action。</p>
<h3>WordPress 2.1</h3>
<p>在WordPress 2.1中，大多数默认filter和action是通过文件wp-includes/default-filters.php来加入的，少数其他的在如下文件中被加入：</p>
<ul>
<li>wp-admin/admin-ajax.php</li>
<li>wp-admin/admin-functions.php</li>
<li>wp-admin/custom-header.php</li>
<li>wp-admin/edit.php</li>
<li>wp-admin/index.php</li>
<li>wp-admin/options-permalink.php</li>
<li>wp-admin/upload-functions.php</li>
<li>wp-admin/upload.php</li>
<li>wp-includes/bookmark.php</li>
<li>wp-includes/general-template.php</li>
<li>wp-includes/kses.php</li>
<li>wp-includes/plugin.php</li>
<li>wp-includes/rewrite.php</li>
<li>wp-includes/template-loader.php</li>
<li>wp-includes/theme.php</li>
</ul>
<h3>WordPress 1.5</h3>
<p>大多数默认的filter和action在WordPress 1.5的文件wp-includes/default-filters.php中被加入。</p>
<h2>你可以覆盖的函数</h2>
<p>除了前面描述的hook（包括action和filter）之外，另一个修改WordPress行为的插件编写方法是覆盖WordPress函数。事实上，WordPress设计了一些让插件重新定义的函数。WordPress通过仅当所有插件都加载之后才加载这些函数的方式来使得这个方式变得容易。</p>
<p>这些函数均定义在文件wp-includes/pluggable.php中，如下是其清单（在2.1版本中）；这些函数中的部分文档可以在<a href="http://www.yeeyan.com/Function_Reference" title="Function Reference"><strong><font color="#003366">Function Reference</font></strong></a>（函数参考-译者注）中找到。</p>
<ul>
<li><tt>set_current_user</tt></li>
<li><tt>wp_set_current_user</tt></li>
<li><tt>wp_get_current_user</tt></li>
</ul>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/security/sql-injection-attack" title="SQL注入攻击-来自微软安全博客的建议">SQL注入攻击-来自微软安全博客的建议</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/google-language-for-wordpress" title="Google Language for WordPress">Google Language for WordPress</a></li><li><a href="http://www.hanguofeng.cn/archives/web-client/google-ajax-language-api-class-reference" title="[译文]Google AJAX Language API对象参考">[译文]Google AJAX Language API对象参考</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-server/wordpress-plugin-api/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->