<?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/"
	>

<channel>
	<title>Ars Longa, Vita Brevis &#187; WordPress</title>
	<atom:link href="http://blog.sjinks.pro/tag/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sjinks.pro</link>
	<description>Quod scripsi, scripsi</description>
	<lastBuildDate>Mon, 06 Feb 2012 17:56:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Обход плагина WP Hashcash</title>
		<link>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/</link>
		<comments>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 05:43:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[спам]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=955</guid>
		<description><![CDATA[Не так страшен JavaScript, как его малюют… WP Hashcash — очередной плагин WordPress для борьбы со спамом. Принцип работы основывается на том, что спам-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Не так страшен <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, как его малюют…</em></h2>
<p><a href="http://wordpress-plugins.feifei.us/hashcash/">WP Hashcash</a> — очередной <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> для борьбы со спамом. Принцип работы основывается на том, что <a href="http://blog.sjinks.pro/tag/spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  спам">спам</a>-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства «человечности» комментатора.<span id="more-955"></span></p>
<p>Недостаток этого подхода заключается в том, что используемый JavaScript является довольно-таки простым; как следствие, его можно «понять» даже из <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>-скрипта.</p>
<p>Пример кода JavaScript, генерируемого плагином:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9557">
        <div class="code javascript" id="p955code7">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> wphc_data <span class="sy0">=</span> <span class="br0">&#91;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#93;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">=</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">^</span><span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> a <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span>wphc_data.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> String.<span class="me1">fromCharCode</span><span class="br0">&#40;</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">eval</span><span class="br0">&#40;</span>a.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Такой JavaScript весьма похож на PHP <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Как следствие, идея обхода плагина заключается в том, чтобы преобразовать JavaScript в PHP и выполнить получившийся PHP-код.</p>
<p>Итак:</p>
<ol>
<li>В PHP нет ключевого слова <code>var</code> (строго говоря, оно там есть, только имеет другое назначение).</li>
<li>В PHP несколько другой синтаксис объявления массива</li>
<li>Идентификаторы в PHP начинаются с доллара</li>
<li>Операция сдвига выглядит как <code>&gt;&gt;</code>, а не <code>&gt;&gt;&gt;</code>.</li>
<li>В PHP нет классов Array, String, но никто не мешает их написать <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>
<p>Наша задача состоит в преобразовании кода, приведённого выше, в нечто подобное:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9558">
        <div class="code php" id="p955code8">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#41;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">=</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span>^<span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">=</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="sy0">,</span> <span class="re0">$a</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Это достигается таким набором правил <code>str_replace()</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9559">
        <div class="code php" id="p955code9">
<span class="re0">$x</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'wphc_data'</span> &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$wphc_data'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var $'</span> &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var '</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'];'</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">');'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'= ['</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'= array('</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'new Array($wphc_data.length)'</span> <span class="sy0">=&gt;</span> <span class="st_h">'array()'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'$wphc_data.length'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'count($wphc_data)'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">' i&lt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">' $i&lt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'[i]'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'[$i]'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'i++'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$i++'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'&gt;&gt;&gt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'&gt;&gt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'a[$i] ='</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$a[$i] ='</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'String.'</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'eval'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;a.join('')&quot;</span> <span class="sy0">=&gt;</span> <span class="st_h">'join(&quot;&quot;, $a)'</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="kw3">array_keys</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="kw3">array_values</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="re0">$s</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>При желании правила можно попытаться оптимизировать, но мне было лень — скрипт ломался на коленке за 10 минут.</p>
<p>Реализация функции <code>fromCharCode</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95510">
        <div class="code php" id="p955code10">
<span class="kw2">function</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="sy0">,</span> <span class="re0">$c</span><span class="sy0">,</span> <span class="re0">$d</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$b</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$d</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>После замены результат нужно вычислить при помощи <code>eval()</code>. После чего получим такой результат:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95511">
        <div class="code javascript" id="p955code11">
<span class="kw2">function</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw1">return</span> 43448 <span class="sy0">*</span> 43448 <span class="sy0">+</span> <span class="nu0">75878</span><span class="sy0">;</span> <span class="br0">&#125;</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Как можно заметить, этот код является одновременно и PHP-кодом, и JavaScript-кодом.</p>
<p>Следующий шаг —</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95512">
        <div class="code php" id="p955code12">
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'wphc_compute();'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">eval</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Результатом выполнения будет число 1887804582.</p>
<p>Как видим, для обхода такой простой защиты не нужен даже интерпретатор JavaScript <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ставим спам в комментариях на службу людям</title>
		<link>http://blog.sjinks.pro/wordpress/931-comment-spam-to-serve-humanity/</link>
		<comments>http://blog.sjinks.pro/wordpress/931-comment-spam-to-serve-humanity/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 04:48:20 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Spamhaus]]></category>
		<category><![CDATA[Stop Forum Spam]]></category>
		<category><![CDATA[спам]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=931</guid>
		<description><![CDATA[Автоматическое отправление автоматического спама на Stop Forum Spam Я давно получаю по несколько тысяч спам-комментариев в день (не то, что мне он мешает — система его отсеивает полностью автоматически) и, как следствие, давно думаю о том, как заставить этот спам служить людям. Начиналось всё созданием чёрных списков типа DNSBL (сюда попадали IP-адреса спамеров) и URIBL (а сюда — рекламируемые [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/931-comment-spam-to-serve-humanity/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Автоматическое отправление автоматического спама на <a href="http://blog.sjinks.pro/tag/stop-forum-spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Stop Forum Spam">Stop Forum Spam</a></em></h2>
<p>Я давно получаю по несколько тысяч <a href="http://blog.sjinks.pro/tag/spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  спам">спам</a>-комментариев в день (не то, что мне он мешает — система его отсеивает полностью автоматически) и, как следствие, давно думаю о том, как заставить этот <a href="http://blog.sjinks.pro/tag/spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  спам">спам</a> служить людям.</p>
<p>Начиналось всё созданием чёрных списков типа DNSBL (сюда попадали IP-адреса спамеров) и URIBL (а сюда — рекламируемые домены), но на раскрутку очередного чёрного списка (а также на его поддержание) банально не было ни сил, ни времени.</p>
<p>Закончилось всё тем, что я прекратил заниматься велосипедостроительством, зарегистрировался на <a href="http://www.stopforumspam.com/">Stop Forum Spam</a> и теперь отсылаю весь полученный спам туда. Хотя я не во всём согласен с SFS, положительным моментом является то, что списки спамеров мониторятся <a href="http://blog.sjinks.pro/tag/spamhaus/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Spamhaus">Spamhaus</a> (<a href="http://www.spamhaus.org/sbl/sbl.lasso?query=SBL115165">пример 1</a>, <a href="http://www.spamhaus.org/sbl/sbl.lasso?query=SBL115164">пример 2</a>). Хотя Spamhaus о себе тоже много думает (блокировать почту на основании того, что с данного IP-адреса идёт форумный спам — <a href="http://blogspambl.com/faq.html#idiot">бред</a>), тем не менее, у Spamhaus больше шансов прикрыть спамера, чем у простого блоггера.</p>
<p>На этом лирическое отступление закончено, далее идёт рассказ о том, как автоматически сообщать об автоматическом спаме в Stop Forum Spam, ибо чем больше отчетов они получат, тем быстрее спамер будет остановлен.<span id="more-931"></span></p>
<p>Идея, на которой строится реализация метода, абсолютно <a href="http://iskariot.ru/development/vs-auto-spam/">не нова</a>, но эффективна.</p>
<p><strong>Шаг первый.</strong> Регистрация на SFS и получение <a href="http://www.stopforumspam.com/signup">API-ключа</a>.</p>
<p><strong>Шаг второй.</strong> Создаём в каталоге с файлами <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> такой простенький файл (например, <code>wp-comments-post2.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>):</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p93117">
        <div class="code php" id="p931code17">
<span class="kw1">require_once</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw4">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'wp-comments-post2.php'</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><strong>Шаг третий.</strong> Добавляем в <code>comments.php</code> используемой темы липовую форму комментариев. Например, такую:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p93118">
        <div class="code xhtml" id="p931code18">
<span class="sc2">&lt;<span class="kw2">div</span> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;display: none; left: -10000px; top: -10000px;&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span>&gt;&lt;<span class="kw2">strong</span>&gt;</span>Пожалуйста, не используйте данную форму комментирования — она исключительно для спамеров.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">form</span> <span class="kw3">method</span><span class="sy0">=</span><span class="st0">&quot;post&quot;</span> <span class="kw3">action</span><span class="sy0">=</span><span class="st0">&quot;/wp-comments-post.php&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;comment-form-author&quot;</span>&gt;&lt;<span class="kw2">label</span>&gt;</span>Имя<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">label</span>&gt;</span> <span class="sc2">&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text&quot;</span> <span class="kw3">size</span><span class="sy0">=</span><span class="st0">&quot;30&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;author&quot;</span><span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;comment-form-email&quot;</span>&gt;&lt;<span class="kw2">label</span>&gt;</span>E-mail<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">label</span>&gt;</span> <span class="sc2">&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text&quot;</span> <span class="kw3">size</span><span class="sy0">=</span><span class="st0">&quot;30&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;email&quot;</span><span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;comment-form-url&quot;</span>&gt;&lt;<span class="kw2">label</span>&gt;</span>Сайт<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">label</span>&gt;&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text&quot;</span> <span class="kw3">size</span><span class="sy0">=</span><span class="st0">&quot;30&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;url&quot;</span><span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;comment-form-comment&quot;</span>&gt;&lt;<span class="kw2">label</span>&gt;</span>Комментарий<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">label</span>&gt;&lt;<span class="kw2">textarea</span> <span class="kw3">rows</span><span class="sy0">=</span><span class="st0">&quot;8&quot;</span> <span class="kw3">cols</span><span class="sy0">=</span><span class="st0">&quot;45&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;comment&quot;</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">textarea</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">p</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;form-submit&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;submit&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Отправить комментарий&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;submit&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;submit&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;hidden&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;comment_post_ID&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;&lt;?php echo get_the_ID(); ?&gt;</span></span>&quot; name=&quot;comment_post_ID&quot;/&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">input</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;hidden&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;0&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;comment_parent&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;comment_parent&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">form</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

<p><strong>Шаг четвёртый.</strong> Меняем нормальную форму комментирования. Всё, что требуется — изменить action формы комментирования с <code>/wp-comments-post.php</code> на <code>/wp-comments-post2.php</code>.</p>
<p>Если для создания формы комментирования используется новомодная функция <code>comment_form()</code> изменить <code>action</code> можно так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p93119">
        <div class="code php" id="p931code19">
<span class="kw2">&lt;?php</span> <br />
&nbsp; &nbsp; <span class="kw3">ob_start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; comment_form<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">ob_get_clean</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'/wp-comments-post.php'</span><span class="sy0">,</span> <span class="st_h">'/wp-comments-post2.php'</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$s</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p><strong>Шаг пятый.</strong> Добавляем кусок кода в файл <code>functions.php</code> используемой темы:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p93120">
        <div class="code php" id="p931code20">
&nbsp; &nbsp; <span class="kw2">function</span> killallspam_pre_comment_approved<span class="br0">&#40;</span><span class="re0">$status</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">false</span> <span class="sy0">!==</span> <span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REQUEST_URI'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st_h">'/wp-comments-post.php'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">isset</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'comment'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'email'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'author'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REMOTE_ADDR'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$apikey</span> &nbsp;<span class="sy0">=</span> <span class="st_h">'API-ключ Stop Forum Spam'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$comment</span> <span class="sy0">=</span> <span class="kw3">stripslashes</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'comment'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$ip</span> &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REMOTE_ADDR'</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$email</span> &nbsp; <span class="sy0">=</span> <span class="kw3">stripslashes</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'email'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$user</span> &nbsp; &nbsp;<span class="sy0">=</span> <span class="kw3">stripslashes</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'author'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$options</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_RETURNTRANSFER <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_AUTOREFERER &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_URL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'http://www.stopforumspam.com/add.php'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_MAXREDIRS &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> 10<span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_FOLLOWLOCATION <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_POST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CURLOPT_POSTFIELDS &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'username='</span> <span class="sy0">.</span> <span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$user</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'&amp;ip_addr='</span> <span class="sy0">.</span> <span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$ip</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'&amp;email='</span> <span class="sy0">.</span> <span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$email</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'&amp;api_key='</span> <span class="sy0">.</span> <span class="re0">$apikey</span> <span class="sy0">.</span> <span class="st_h">'&amp;evidence='</span> <span class="sy0">.</span> <span class="kw3">urlencode</span><span class="br0">&#40;</span><span class="re0">$comment</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$ch</span> <span class="sy0">=</span> <span class="kw3">curl_init</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt_array</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> <span class="re0">$options</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_exec</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_close</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">'spam'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$status</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">function_exists</span><span class="br0">&#40;</span><span class="st_h">'add_filter'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; add_filter<span class="br0">&#40;</span><span class="st_h">'pre_comment_approved'</span><span class="sy0">,</span> <span class="st_h">'killallspam_pre_comment_approved'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Вместо <code>API-ключ Stop Forum Spam</code> подставляем свой API-ключ.</p>
<p>Вместо возни с cURL можно использовать API-функцию WordPress <code>wp_remote_post()</code>.</p>
<p><strong>Шаг шестой.</strong> Радуемся жизни <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/931-comment-spam-to-serve-humanity/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/931-comment-spam-to-serve-humanity/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>SQL Injection Vulnerability в Z-Vote 1.1</title>
		<link>http://blog.sjinks.pro/security/902-sql-injection-vulnerability-z-vote/</link>
		<comments>http://blog.sjinks.pro/security/902-sql-injection-vulnerability-z-vote/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 19:32:49 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Патчи]]></category>
		<category><![CDATA[path disclosure]]></category>
		<category><![CDATA[SQL-инъекция]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[безопасность]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=902</guid>
		<description><![CDATA[Исправление уязвимостей в плагине WordPress Z-Vote 1.1 В плагине WordPress Z-Vote 1.1 была обнаружена уязвимость, позволяющая злоумышленнику выполнять произвольные запросы к базе данных (уязвимость типа «SQL-инъекция»). Уязвимость существует из-за неправильного использования метода wpdb::prepare() и отсутствия проверки и очистки переменной $_GET['zvote']. Уязвимость позволяет злоумышленнику изменять запросы к базе данных, выполнять произвольные запросы, читать или изменять конфиденциальную информацию. Вторая [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/902-sql-injection-vulnerability-z-vote/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Исправление уязвимостей в плагине <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> Z-Vote 1.1</em></h2>
<p>В плагине WordPress Z-Vote 1.1 была <a href="http://www.exploit-db.com/exploits/16218/">обнаружена</a> <a href="http://blog.sjinks.pro/tag/vulnerability/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  уязвимость">уязвимость</a>, позволяющая злоумышленнику выполнять произвольные запросы к базе данных (<a href="http://blog.sjinks.pro/tag/vulnerability/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  уязвимость">уязвимость</a> типа «<a href="http://blog.sjinks.pro/tag/sql-injection/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SQL-инъекция">SQL-инъекция</a>»).</p>
<p>Уязвимость существует из-за неправильного использования метода <span class="codebox"><code class="php">wpdb<span class="sy0">::</span><span class="me2">prepare</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> и отсутствия проверки и очистки переменной <code>$_GET['zvote']</code>.</p>
<p>Уязвимость позволяет злоумышленнику изменять запросы к базе данных, выполнять произвольные запросы, читать или изменять конфиденциальную информацию.<span id="more-902"></span><br />
Вторая уязвимость (незначительная по сравнению с SQL-инъекцией) — раскрытие пути к плагину (<a href="http://blog.sjinks.pro/tag/path-disclosure/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  path disclosure">path disclosure</a>) при прямом доступе к файлу плагина.</p>
<p><strong><a href='http://static.sjinks.info/wp-content/uploads/2011/02/z-vote.diff'>Патч, исправляющий уязвимости в Z-Vote 1.1</a>:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p90222">
        <div class="code diff" id="p902code22">
diff -uwdBrN z-vote.orig/zvote.php z-vote/zvote.php<br />
<span class="re3">--- z-vote.orig/zvote.php &nbsp; <span class="nu0">2011</span>-02-<span class="nu0">25</span> <span class="nu0">21</span>:05:<span class="nu0">44.000000000</span> +0200</span><br />
<span class="re4">+++ z-vote/zvote.php&nbsp; &nbsp; <span class="nu0">2011</span>-02-<span class="nu0">25</span> <span class="nu0">21</span>:<span class="nu0">10</span>:<span class="nu0">46.531798756</span> +0200</span><br />
<span class="re6">@@ -<span class="nu0">9</span>,<span class="nu0">6</span> +<span class="nu0">9</span>,<span class="nu0">8</span> @@</span><br />
&nbsp; &nbsp;License: GPL <br />
&nbsp;*/<br />
&nbsp;<br />
<span class="re8">+ &nbsp; defined<span class="br0">&#40;</span>'ABSPATH'<span class="br0">&#41;</span> or die<span class="br0">&#40;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+</span><br />
&nbsp;// --- DEFINITIONS<br />
&nbsp;<br />
&nbsp; &nbsp; //define where zvote is installed on the wordpres system. In 99.9% of the case the path below is correct.<br />
<span class="re6">@@ -<span class="nu0">271</span>,<span class="nu0">7</span> +<span class="nu0">273</span>,<span class="nu0">7</span> @@</span><br />
&nbsp;function zVote_getEntry<span class="br0">&#40;</span>$postid<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; global $wpdb;<br />
&nbsp;<br />
<span class="re7">- &nbsp; $entries = $wpdb-&gt;get_results<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT * FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = &quot; . $postid . &quot;&quot;<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; $entries = $wpdb-&gt;get_results<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT * FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = %d&quot;, $postid<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; return $entries;<br />
&nbsp;<span class="br0">&#125;</span><br />
<span class="re6">@@ -<span class="nu0">282</span>,<span class="nu0">7</span> +<span class="nu0">284</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; global $wpdb;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; $votes = <span class="nu0">0</span>;<br />
<span class="re7">- &nbsp; $votes = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT COUNT<span class="br0">&#40;</span>*<span class="br0">&#41;</span> FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = &quot; . $postid . &quot;&quot;<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; $votes = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT COUNT<span class="br0">&#40;</span>*<span class="br0">&#41;</span> FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = %d&quot;, $postid<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; return $votes;<br />
&nbsp;<span class="br0">&#125;</span><br />
<span class="re6">@@ -<span class="nu0">292</span>,<span class="nu0">7</span> +<span class="nu0">294</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; global $wpdb;<br />
&nbsp; &nbsp; <br />
<span class="re7">- &nbsp; $votes = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;DELETE FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = &quot; . $postid . &quot;&quot;<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; $votes = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;DELETE FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = %d&quot;, $postid<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; return $votes;<br />
&nbsp;<span class="br0">&#125;</span><br />
<span class="re6">@@ -<span class="nu0">353</span>,<span class="nu0">7</span> +<span class="nu0">355</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; global $wpdb;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; //ipcheck for now, will expand to userid-check, based on the user setting in version 1.5<br />
<span class="re7">- &nbsp; $ipcheck = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT id FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = &quot; . $postid . &quot; AND userip = \&quot;&quot; . $_SERVER<span class="br0">&#91;</span>'REMOTE_ADDR'<span class="br0">&#93;</span> . &quot;\&quot;&quot;<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; $ipcheck = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT id FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = %d AND userip = %s&quot;, $postid, $_SERVER<span class="br0">&#91;</span>'REMOTE_ADDR'<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; $wpdb-&gt;insert<span class="br0">&#40;</span> $wpdb-&gt;prefix . 'zvotedata', array<span class="br0">&#40;</span> 'postid' =&gt; $postid, 'userip' =&gt; $_SERVER<span class="br0">&#91;</span>'REMOTE_ADDR'<span class="br0">&#93;</span>, 'userid' =&gt; 0, 'time' =&gt; time<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>, array<span class="br0">&#40;</span> '%d','%s', '%d', '%d' <span class="br0">&#41;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <br />
<span class="re6">@@ -<span class="nu0">365</span>,<span class="nu0">7</span> +<span class="nu0">367</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; global $wpdb, $wp_query, $redirect_meta_key;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; //ipcheck for now, will expand to userid-check, based on the user setting in version 1.5<br />
<span class="re7">- &nbsp; $ipcheck = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT id FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = &quot; . $postid . &quot; AND userip = \&quot;&quot; . $_SERVER<span class="br0">&#91;</span>'REMOTE_ADDR'<span class="br0">&#93;</span> . &quot;\&quot;&quot;<span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; $ipcheck = $wpdb-&gt;get_var<span class="br0">&#40;</span>$wpdb-&gt;prepare<span class="br0">&#40;</span>&quot;SELECT id FROM &quot; . $wpdb-&gt;prefix . &quot;zvotedata WHERE postid = %d AND userip = %d&quot;, $postid, $_SERVER<span class="br0">&#91;</span>'REMOTE_ADDR'<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; if <span class="br0">&#40;</span>!$ipcheck<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; //ok to vote, register vote<br />
<span class="re6">@@ -<span class="nu0">382</span>,<span class="nu0">7</span> +<span class="nu0">384</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //send user to post<br />
<span class="re7">- &nbsp; &nbsp; &nbsp; header<span class="br0">&#40;</span>'Location: ' .$injectionPoint<span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; wp_redirect<span class="br0">&#40;</span>$injectionPoint<span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; exit;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span> else <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; //user already registered, push to entry-page and inform the user.<br />
<span class="re6">@@ -<span class="nu0">394</span>,<span class="nu0">7</span> +<span class="nu0">396</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $injectionPoint = $post . '?zvoters=2';<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span class="re7">- &nbsp; &nbsp; &nbsp; header<span class="br0">&#40;</span>'Location: ' .$injectionPoint<span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; wp_redirect<span class="br0">&#40;</span>$injectionPoint<span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; exit;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; exit;
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/902-sql-injection-vulnerability-z-vote/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/902-sql-injection-vulnerability-z-vote/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Межсайтовый скриптинг в Register Plus</title>
		<link>http://blog.sjinks.pro/security/895-register-plus-xss-vulnerability/</link>
		<comments>http://blog.sjinks.pro/security/895-register-plus-xss-vulnerability/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 12:59:36 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[path disclosure]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=895</guid>
		<description><![CDATA[Патч, исправляющий уязвимости XSS и FPD В плагине Register Plus 3.5.1 обнаружена уязвимость, позволяющая провести удалённому пользователю XSS-атаку. Уязвимость связана с отсутствием экранирования специальных символов при выводе данных, полученных от пользователя, что позволяет злоумышленнику выполнить произвольный код сценария в браузере жертвы в контексте безопасности уязвимого сайта. Судя по дате последнего изменения, плагин автором больше не поддерживается; [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/895-register-plus-xss-vulnerability/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em><a href="http://blog.sjinks.pro/tag/patch/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  патч">Патч</a>, исправляющий уязвимости <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a> и FPD</em></h2>
<p>В плагине <a href="http://wordpress.org/extend/plugins/register-plus/">Register Plus</a> 3.5.1 <a href="http://websecurity.com.ua/4539">обнаружена</a> <a href="http://blog.sjinks.pro/tag/vulnerability/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  уязвимость">уязвимость</a>, позволяющая провести удалённому пользователю XSS-атаку.</p>
<p>Уязвимость связана с отсутствием экранирования специальных символов при выводе данных, полученных от пользователя, что позволяет злоумышленнику выполнить произвольный код сценария в браузере жертвы в контексте безопасности уязвимого сайта.</p>
<p>Судя по дате последнего изменения, <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> автором больше не поддерживается; тем не менее, пользователи <a href="http://wordpress.org/support/topic/plugin-register-plus-works-with-wp3-but-with-minor-issues?replies=2">не оставляют попытки</a> использования плагина с новыми версиями <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>.<span id="more-895"></span></p>
<p>Тем же исследователем была обнаружена уязвимость типа full <a href="http://blog.sjinks.pro/tag/path-disclosure/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  path disclosure">path disclosure</a> (ей подвержены очень многие плагины и сам WordPress в том числе).</p>
<p><strong><a href="http://static.sjinks.info/wp-content/uploads/2011/02/register-plus.diff">Скачать патч для плагина Register Plus</a>.</strong></p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/895-register-plus-xss-vulnerability/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/895-register-plus-xss-vulnerability/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>KSES в WordPress: можно ли проще?</title>
		<link>http://blog.sjinks.pro/wordpress/894-kses-wordpress-could-it-be-simplier/</link>
		<comments>http://blog.sjinks.pro/wordpress/894-kses-wordpress-could-it-be-simplier/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 06:07:09 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[KSES]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=894</guid>
		<description><![CDATA[Регулярные выражения против DOM XML Вчера мне довелось разбираться с тем, как работает KSES в WordPress. KSES (рекурсивный акроним от KSES Strips Evil Scripts) — подсистема в WordPress (изначально написанная Ulf Harnhammar), предназначенная для проверки и очистки текста, введённого пользователем: она позволяет задать список допустимых тэгов, стилей и протоколов и на основе этих параметров убрать из текста [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/894-kses-wordpress-could-it-be-simplier/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Регулярные выражения против DOM XML</em></h2>
<p>Вчера мне довелось разбираться с тем, как работает <a href="http://blog.sjinks.pro/tag/kses/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  KSES">KSES</a> в <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>.</p>
<p>KSES (рекурсивный акроним от KSES Strips Evil Scripts) — подсистема в WordPress (изначально написанная Ulf Harnhammar), предназначенная для проверки и очистки текста, введённого пользователем: она позволяет задать список допустимых тэгов, стилей и протоколов и на основе этих параметров убрать из текста пользователя всё, что им не соответствует.</p>
<p>KSES является довольно стабильной подсистемой; что немаловажно, KSES <em>работает</em>. Работает —  не трогай, а то сломаешь…<span id="more-894"></span></p>
<p>Лично мне в KSES не нравится использование регулярных выражений. Одна из причин — теория разработки компиляторов. Известно, что <a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a> — это грамматика второго типа в иерархии Хомского (контекстно-свободная грамматика), а регулярные выражения — грамматика третьего типа (регулярная грамматика). Грамматика второго типа является более сложной, нежели грамматика третьего типа. Как следствие, описать более простой грамматикой то, что соответствует более сложной, очень трудно (вряд ли возможно на 100%, но это моё мнение).</p>
<p>Что плохо, среди <a href="http://codex.wordpress.org/Automated_Testing">тестов WordPress</a> я не нашёл тестов для KSES. Что может означать, что, вероятно, никто из разработчиков не строил и не проверял граф путей в KSES; как следствие, не гарантии, что при граничных условиях всё будет работать нормально.</p>
<p>Другая причина, по которой я не люблю регулярные выражения — это скорость: особой производительностью они не отличаются. Хотя с другой стороны, объёмы проверяемого текста не так велики, чтобы KSES оказывал существенное влияние на <a href="http://blog.sjinks.pro/tag/performance/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  производительность">производительность</a>.</p>
<p>Каковы альтернативы? <a href="http://htmlpurifier.org/comparison">Обзор</a>.</p>
<p>На <em>мой</em> взгляд, самая удобная альтернатива — использование DOM XML и работа с полученным деревом. Тем более, что в <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> есть соответствующая поддержка. А парсер на C в любом случае быстрее парсера на <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>.</p>
<p>Парсер DOM XML в PHP позволяет работать даже с некорректным HTML. Что означает, что он берёт на себя решение проблемы с неправильно закрытыми или незакрытыми тэгами. Парсер понимает HTML entities и преобразует их в нормальный текст. Что означает, что не нужно возиться с разными форматами записи entities и переводить их к одному виду (чему в KSES уделено не мало кода). И так далее.</p>
<p>Для проверки некоторых идей я написал небольшой класс, который делает <em>почти</em> то же самое, что и KSES, только иначе <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Я ни в коем случае не рассматриваю его как замену KSES.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p89424">
        <div class="code php" id="p894code24">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw2">class</span> Xex<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$protocols</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$tags</span> &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$css</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$strip_comments</span> &nbsp; &nbsp;<span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$strip_script_text</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$strip_style_text</span> &nbsp;<span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$script_text</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$style_text</span> &nbsp;<span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$trim_text</span> <span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="kw1">array</span> <span class="re0">$tags</span> <span class="sy0">=</span> <span class="kw4">null</span><span class="sy0">,</span> <span class="kw1">array</span> <span class="re0">$protocols</span> <span class="sy0">=</span> <span class="kw4">null</span><span class="sy0">,</span> <span class="kw1">array</span> <span class="re0">$css</span> <span class="sy0">=</span> <span class="kw4">null</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">null</span> <span class="sy0">!==</span> <span class="re0">$tags</span><span class="br0">&#41;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">tags</span> <span class="sy0">=</span> <span class="re0">$tags</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">null</span> <span class="sy0">!==</span> <span class="re0">$protocols</span><span class="br0">&#41;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">protocols</span> <span class="sy0">=</span> <span class="kw3">array_combine</span><span class="br0">&#40;</span><span class="re0">$protocols</span><span class="sy0">,</span> <span class="re0">$protocols</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">null</span> <span class="sy0">!==</span> <span class="re0">$css</span><span class="br0">&#41;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">css</span> <span class="sy0">=</span> <span class="kw3">array_combine</span><span class="br0">&#40;</span><span class="re0">$css</span><span class="sy0">,</span> <span class="re0">$css</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">protected</span> <span class="kw2">function</span> checkProtocols<span class="br0">&#40;</span><span class="re0">$str</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="kw1">array</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\r</span>&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\t</span>&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$str</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">explode</span><span class="br0">&#40;</span><span class="st_h">':'</span><span class="sy0">,</span> <span class="re0">$s</span><span class="sy0">,</span> 2<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// See http://tools.ietf.org/html/rfc3986#section-3.1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">preg_match</span><span class="br0">&#40;</span><span class="st_h">'/^[a-z][a-z0-9+.-]*$/'</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="sy0">!</span><span class="kw1">isset</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">protocols</span><span class="br0">&#91;</span><span class="re0">$s</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">''</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$str</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">protected</span> <span class="kw2">function</span> sanitizeCss<span class="br0">&#40;</span><span class="re0">$css</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$css</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="kw1">array</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span><span class="st0">&quot;<span class="es1">\r</span>&quot;</span><span class="sy0">,</span><span class="st0">&quot;<span class="es1">\t</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$css</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">preg_match</span><span class="br0">&#40;</span><span class="st_h">'![\\(&amp;=}]|/\\*!'</span><span class="sy0">,</span> <span class="re0">$css</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">''</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$arr</span> <span class="sy0">=</span> <span class="kw3">explode</span><span class="br0">&#40;</span><span class="st_h">';'</span><span class="sy0">,</span> <span class="kw3">trim</span><span class="br0">&#40;</span><span class="re0">$css</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$css</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$arr</span> <span class="kw1">as</span> <span class="re0">$x</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$x</span> <span class="sy0">=</span> <span class="kw3">trim</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$found</span> <span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">false</span> <span class="sy0">===</span> <span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="sy0">,</span> <span class="st_h">':'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$found</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parts</span> <span class="sy0">=</span> <span class="kw3">explode</span><span class="br0">&#40;</span><span class="st_h">':'</span><span class="sy0">,</span> <span class="re0">$x</span><span class="sy0">,</span> 2<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">isset</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">css</span><span class="br0">&#91;</span><span class="kw3">rtrim</span><span class="br0">&#40;</span><span class="re0">$parts</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$found</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$found</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$css</span> <span class="sy0">.=</span> <span class="re0">$x</span> <span class="sy0">.</span> <span class="st_h">';'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$css</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">protected</span> <span class="kw2">function</span> parseDOM<span class="br0">&#40;</span>DOMNode <span class="re0">$el</span><span class="sy0">,</span> DOMNode <span class="re0">$new</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">nodeType</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> XML_ELEMENT_NODE<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$prefix</span> <span class="sy0">=</span> <span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">prefix</span> ? <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">prefix</span> <span class="sy0">.</span> <span class="st_h">':'</span><span class="br0">&#41;</span> <span class="sy0">:</span> <span class="st_h">''</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$tag</span> &nbsp; &nbsp;<span class="sy0">=</span> <span class="re0">$prefix</span> <span class="sy0">.</span> <span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">tagName</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">isset</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">tags</span><span class="br0">&#91;</span><span class="re0">$tag</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$n</span> <span class="sy0">=</span> <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">cloneNode</span><span class="br0">&#40;</span><span class="kw4">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">hasAttributes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$attrs</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">tags</span><span class="br0">&#91;</span><span class="re0">$tag</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">attributes</span> <span class="kw1">as</span> <span class="re0">$a</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw1">isset</span><span class="br0">&#40;</span><span class="re0">$attrs</span><span class="br0">&#91;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$n</span><span class="sy0">-&gt;</span><span class="me1">removeAttribute</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="st_h">'style'</span> <span class="sy0">==</span> <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$css</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">sanitizeCss</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">value</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$css</span> <span class="sy0">!=</span> <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$n</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="sy0">,</span> <span class="re0">$css</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="kw3">in_array</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="sy0">,</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="st_h">'xmlns'</span><span class="sy0">,</span> <span class="st_h">'profile'</span><span class="sy0">,</span> <span class="st_h">'href'</span><span class="sy0">,</span> <span class="st_h">'src'</span><span class="sy0">,</span> <span class="st_h">'cite'</span><span class="sy0">,</span> <span class="st_h">'classid'</span><span class="sy0">,</span> <span class="st_h">'codebase'</span><span class="sy0">,</span> <span class="st_h">'data'</span><span class="sy0">,</span> <span class="st_h">'usemap'</span><span class="sy0">,</span> <span class="st_h">'longdesc'</span><span class="sy0">,</span> <span class="st_h">'action'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">checkProtocols</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">value</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$s</span> <span class="sy0">!=</span> <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$n</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">name</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$tag</span> <span class="sy0">==</span> <span class="st_h">'script'</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">strip_script_text</span> <span class="sy0">||</span> <span class="re0">$tag</span> <span class="sy0">==</span> <span class="st_h">'style'</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">strip_style_text</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$n</span> <span class="sy0">=</span> <span class="re0">$new</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">hasChildNodes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">childNodes</span> <span class="kw1">as</span> <span class="re0">$e</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">parseDOM</span><span class="br0">&#40;</span><span class="re0">$e</span><span class="sy0">,</span> <span class="re0">$n</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> XML_TEXT_NODE<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">trim_text</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">cloneNode</span><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="kw2">new</span> DOMText<span class="br0">&#40;</span><span class="kw3">trim</span><span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">wholeText</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> XML_CDATA_SECTION_NODE<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">cloneNode</span><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> XML_COMMENT_NODE<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parent</span> <span class="sy0">=</span> <span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">parentNode</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$parent</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$parent</span><span class="sy0">-&gt;</span><span class="me1">tagName</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$prefix</span> <span class="sy0">=</span> <span class="re0">$parent</span><span class="sy0">-&gt;</span><span class="me1">prefix</span> ? <span class="br0">&#40;</span><span class="re0">$parent</span><span class="sy0">-&gt;</span><span class="me1">prefix</span> <span class="sy0">.</span> <span class="st_h">':'</span><span class="br0">&#41;</span> <span class="sy0">:</span> <span class="st_h">''</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$tag</span> &nbsp; &nbsp;<span class="sy0">=</span> <span class="re0">$prefix</span> <span class="sy0">.</span> <span class="re0">$parent</span><span class="sy0">-&gt;</span><span class="me1">tagName</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="st_h">'style'</span> <span class="sy0">==</span> <span class="re0">$tag</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">style_text</span> <span class="sy0">||</span> <span class="st_h">'script'</span> <span class="sy0">==</span> <span class="re0">$tag</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">script_text</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="kw2">new</span> DOMText<span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">strip_comments</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="re0">$el</span><span class="sy0">-&gt;</span><span class="me1">cloneNode</span><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">default</span><span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> sanitize<span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span> <span class="sy0">=</span> <span class="kw2">new</span> DOMDocument<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">recover</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">strictErrorChecking</span> <span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">substituteEntities</span> &nbsp;<span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">resolveExternals</span> &nbsp; &nbsp;<span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">formatOutput</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$old</span> <span class="sy0">=</span> <span class="kw3">libxml_use_internal_errors</span><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="kw3">chr</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;([^a-z\\?\\!/])!i'</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;$1'</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;((?:[\\?\\!/]\\s*)?[a-z][^&gt;]*)(?=&lt;)!i'</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;$1'</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">@</span><span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">loadHTML</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">libxml_use_internal_errors</span><span class="br0">&#40;</span><span class="re0">$old</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span> <span class="sy0">=</span> <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">createDocumentFragment</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">appendChild</span><span class="br0">&#40;</span><span class="kw2">new</span> DOMElement<span class="br0">&#40;</span><span class="st_h">'wrap'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">parseDOM</span><span class="br0">&#40;</span><span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">documentElement</span><span class="sy0">,</span> <span class="re0">$new</span><span class="sy0">-&gt;</span><span class="me1">firstChild</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">replaceChild</span><span class="br0">&#40;</span><span class="re0">$new</span><span class="sy0">,</span> <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">documentElement</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">saveXML</span><span class="br0">&#40;</span><span class="re0">$dom</span><span class="sy0">-&gt;</span><span class="me1">documentElement</span><span class="sy0">,</span> LIBXML_NOEMPTYTAG<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">substr</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="sy0">,</span> <span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="sy0">,</span> <span class="st_h">'&lt;wrap&gt;'</span><span class="br0">&#41;</span> <span class="sy0">+</span> 6<span class="sy0">,</span> <span class="sy0">-</span>7<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>Менее 200 строк против почти полутора тысяч.</p>
<p>На 45-килобайтном документе DOM быстрее KSES от 5 до 9 раз.<br />
На 90-килобайтном документе DOM быстрее KSES от 6 до 9 раз.<br />
На 180-килобайтном документе DOM быстрее KSES от 9 до 10 раз.</p>
<p>Производительность зависит от количества тэгов и стилей (разбор стилей реализован практически одинаково). Например, на домашней странице Google XEX может опережать KSES в 25 раз; если же соединить домашнюю страницу Google саму с собой 4 раза, разница во времени сокращается.</p>
<p>На домашней странице WordPress разница в 7 раз.</p>
<p>На <a href="http://blog.sjinks.pro/test/accordion/accordion1.html">этой странице</a> разница в 4 раза.</p>
<p>Всё-таки KSES очень медленный…</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/894-kses-wordpress-could-it-be-simplier/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/894-kses-wordpress-could-it-be-simplier/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Межсайтовый скриптинг в плагине Accept Signups 0.1</title>
		<link>http://blog.sjinks.pro/security/892-accept-signups-xss/</link>
		<comments>http://blog.sjinks.pro/security/892-accept-signups-xss/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 04:10:34 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[безопасность]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=892</guid>
		<description><![CDATA[Исправление OSVDB-70101 для плагина Accept Signups В плагине Accept Signups 1.0 обнаружена уязвимость, позволяющая провести удалённому пользователю XSS-атаку. Уязвимость связана с отсутствием обработки входных данных в параметре email, передаваемом файлу wp-content/plugins/accept-signups/accept-signups_submit.php, а также с отсутствием экранирования специальных символов при выводе данных в wp-content/plugins/accept-signups/accept-signups.php. Уязвимость позволяет при помощи специально сформированного URL выполнить произвольный код сценария в браузере [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/892-accept-signups-xss/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Исправление OSVDB-70101 для плагина Accept Signups</em></h2>
<p>В плагине <a href="http://wordpress.org/extend/plugins/accept-signups/">Accept Signups</a> 1.0 <a href="http://osvdb.org/show/osvdb/70101">обнаружена</a> <a href="http://blog.sjinks.pro/tag/vulnerability/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  уязвимость">уязвимость</a>, позволяющая провести удалённому пользователю <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>-атаку.</p>
<p>Уязвимость связана с отсутствием обработки входных данных в параметре <code>email</code>, передаваемом файлу <code>wp-content/plugins/accept-signups/accept-signups_submit.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>, а также с отсутствием экранирования специальных символов при выводе данных в <code>wp-content/plugins/accept-signups/accept-signups.php</code>.</p>
<p>Уязвимость позволяет при помощи специально сформированного URL выполнить произвольный код сценария в браузере жертвы в контексте безопасности уязвимого сайта.<span id="more-892"></span></p>
<p><strong><a href='http://static.sjinks.info/wp-content/uploads/2011/02/accept-signups.diff'>Патч для плагина Accept Signups 0.1</a>:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p89226">
        <div class="code diff" id="p892code26">
diff -uwdBrN accept-signups.orig/accept-signups.php accept-signups/accept-signups.php<br />
<span class="re3">--- accept-signups.orig/accept-signups.php&nbsp; <span class="nu0">2010</span>-<span class="nu0">12</span>-<span class="nu0">21</span> <span class="nu0">11</span>:07:<span class="nu0">21.000000000</span> +0200</span><br />
<span class="re4">+++ accept-signups/accept-signups.php &nbsp; <span class="nu0">2011</span>-02-09 06:06:<span class="nu0">33.612991546</span> +0200</span><br />
<span class="re6">@@ -<span class="nu0">223</span>,<span class="nu0">7</span> +<span class="nu0">223</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; $r = $wpdb-&gt;get_results<span class="br0">&#40;</span>$sql, ARRAY_A<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; $xml = '&lt;accept-signups&gt;';<br />
&nbsp; &nbsp; foreach<span class="br0">&#40;</span>$r as $k=&gt;$v<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="re7">- &nbsp; &nbsp; &nbsp; $xml .= '&lt;signup email=&quot;' . $v<span class="br0">&#91;</span>&quot;email&quot;<span class="br0">&#93;</span> . '&quot; ip=&quot;' . $v<span class="br0">&#91;</span>&quot;ip&quot;<span class="br0">&#93;</span> . '&quot; timestamp=&quot;' . $v<span class="br0">&#91;</span>&quot;timestamp&quot;<span class="br0">&#93;</span> . '&quot; /&gt;';</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; $xml .= '&lt;signup email=&quot;' . esc_attr<span class="br0">&#40;</span>$v<span class="br0">&#91;</span>&quot;email&quot;<span class="br0">&#93;</span><span class="br0">&#41;</span> . '&quot; ip=&quot;' . $v<span class="br0">&#91;</span>&quot;ip&quot;<span class="br0">&#93;</span> . '&quot; timestamp=&quot;' . $v<span class="br0">&#91;</span>&quot;timestamp&quot;<span class="br0">&#93;</span> . '&quot; /&gt;';</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; $xml .= '&lt;/accept-signups&gt;';<br />
&nbsp; &nbsp; file_put_contents<span class="br0">&#40;</span>ABSPATH . 'wp-content/plugins/accept-signups/accept-signups.xml', $xml<span class="br0">&#41;</span>;<br />
<span class="re6">@@ -<span class="nu0">290</span>,<span class="nu0">7</span> +<span class="nu0">290</span>,<span class="nu0">7</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if <span class="br0">&#40;</span>strpos<span class="br0">&#40;</span>$v1, '@'<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $email = $v1;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="re7">- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $html .= '&lt;td valign=&quot;top&quot; align=&quot;center&quot; class=&quot;acceptSignupsCell&quot;&gt;&amp;nbsp;&amp;nbsp;' . $v1 . '&amp;nbsp;&amp;nbsp;&lt;/td&gt;'; </span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $html .= '&lt;td valign=&quot;top&quot; align=&quot;center&quot; class=&quot;acceptSignupsCell&quot;&gt;&amp;nbsp;&amp;nbsp;' . esc_html<span class="br0">&#40;</span>$v1<span class="br0">&#41;</span> . '&amp;nbsp;&amp;nbsp;&lt;/td&gt;'; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; $html .= '&lt;td valign=&quot;top&quot; align=&quot;center&quot; class=&quot;acceptSignupsCell&quot; valign=&quot;bottom&quot;&gt;&lt;input type=&quot;checkbox&quot; name=&quot;acceptSignupsDeleteCB?' . acceptSignupsEncode<span class="br0">&#40;</span>$email<span class="br0">&#41;</span> . '&quot; id=&quot;acceptSignupsDeleteCB&quot;&gt;&lt;/td&gt;'; <br />
&nbsp; &nbsp; &nbsp; &nbsp; $html .= '&lt;/tr&gt;';<br />
diff -uwdBrN accept-signups.orig/accept-signups_submit.php accept-signups/accept-signups_submit.php<br />
<span class="re3">--- accept-signups.orig/accept-signups_submit.php &nbsp; <span class="nu0">2010</span>-<span class="nu0">12</span>-<span class="nu0">21</span> <span class="nu0">11</span>:07:<span class="nu0">21.000000000</span> +0200</span><br />
<span class="re4">+++ accept-signups/accept-signups_submit.php&nbsp; &nbsp; <span class="nu0">2011</span>-02-09 06:03:<span class="nu0">04.017742924</span> +0200</span><br />
<span class="re6">@@ -<span class="nu0">1</span>,<span class="nu0">6</span> +<span class="nu0">1</span>,<span class="nu0">5</span> @@</span><br />
&nbsp;&lt;?php<br />
<span class="re7">-require_once<span class="br0">&#40;</span>'../../../wp-config.php'<span class="br0">&#41;</span>;</span><br />
<span class="re7">-require_once<span class="br0">&#40;</span>'../../../wp-includes/wp-db.php'<span class="br0">&#41;</span>;</span><br />
<span class="re8">+require_once<span class="br0">&#40;</span>'../../../wp-load.php'<span class="br0">&#41;</span>;</span><br />
&nbsp;<br />
&nbsp;if <span class="br0">&#40;</span>true<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; if <span class="br0">&#40;</span>isset<span class="br0">&#40;</span>$_GET<span class="br0">&#91;</span>'email'<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="re6">@@ -<span class="nu0">9</span>,<span class="nu0">6</span> +<span class="nu0">8</span>,<span class="nu0">16</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if <span class="br0">&#40;</span>hasEmail<span class="br0">&#40;</span>$_GET<span class="br0">&#91;</span>'email'<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo get_option<span class="br0">&#40;</span>'accept-signups-email-already-exists'<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> else <span class="br0">&#123;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $email = stripslashes<span class="br0">&#40;</span>$_GET<span class="br0">&#91;</span>'email'<span class="br0">&#93;</span><span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if <span class="br0">&#40;</span>function_exists<span class="br0">&#40;</span>'filter_var'<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if <span class="br0">&#40;</span>!filter_var<span class="br0">&#40;</span>$email, FILTER_VALIDATE_EMAIL<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; die<span class="br0">&#40;</span>'-1'<span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elseif <span class="br0">&#40;</span>!preg_match<span class="br0">&#40;</span>'/^<span class="br0">&#40;</span><span class="br0">&#91;</span>a-z0-<span class="nu0">9</span>_\-\.<span class="br0">&#93;</span><span class="br0">&#41;</span>+\@<span class="br0">&#40;</span><span class="br0">&#91;</span>a-z0-<span class="nu0">9</span>_\-\.<span class="br0">&#93;</span><span class="br0">&#41;</span>+\.<span class="br0">&#40;</span><span class="br0">&#91;</span>a-z<span class="br0">&#93;</span><span class="br0">&#123;</span><span class="nu0">2</span>,<span class="nu0">4</span><span class="br0">&#125;</span><span class="br0">&#41;</span>$/i', $email<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; die<span class="br0">&#40;</span>'-1'<span class="br0">&#41;</span>;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></span><br />
<span class="re8">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saveEmail<span class="br0">&#40;</span>$_GET<span class="br0">&#91;</span>'email'<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo get_option<span class="br0">&#40;</span>'accept-signups-email-saved'<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Помимо OSVDB-70101, данный <a href="http://blog.sjinks.pro/tag/patch/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  патч">патч</a> исправляет еще пару мелких недочётов.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/892-accept-signups-xss/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/892-accept-signups-xss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Межсайтовый скриптинг в WordPress BezahlCode-Generator 1.0</title>
		<link>http://blog.sjinks.pro/security/890-bezahlcode-generator-xss/</link>
		<comments>http://blog.sjinks.pro/security/890-bezahlcode-generator-xss/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 03:13:15 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[безопасность]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=890</guid>
		<description><![CDATA[Патч для BezahlCode-Generator, исправляющий уязвимость В плагине BezahlCode-Generator 1.0 обнаружена уязвимость, позволяющая провести удалённому пользователю XSS-атаку. Уязвимость связана с отсутствием обработки входных данных в параметрах gen_name, gen_account, gen_BNC, gen_amount, gen_reason в bezahlcode-generator/der_generator.php. Удаленный пользователь может с помощью специально сформированного запроса выполнить произвольный код сценария в браузере жертвы в контексте безопасности уязвимого сайта. Патч для BezahlCode-Generator 1.0: [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/890-bezahlcode-generator-xss/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Патч для BezahlCode-Generator, исправляющий <a href="http://blog.sjinks.pro/tag/vulnerability/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  уязвимость">уязвимость</a></em></h2>
<p>В плагине <a href="http://wordpress.org/extend/plugins/bezahlcode-generator/">BezahlCode-Generator</a> 1.0 обнаружена уязвимость, позволяющая провести удалённому пользователю <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>-атаку. Уязвимость связана с отсутствием обработки входных данных в параметрах <code>gen_name</code>, <code>gen_account</code>, <code>gen_BNC</code>, <code>gen_amount</code>, <code>gen_reason</code> в <code>bezahlcode-generator/der_generator.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>.</p>
<p>Удаленный пользователь может с помощью специально сформированного запроса выполнить произвольный код сценария в браузере жертвы в контексте безопасности уязвимого сайта.<span id="more-890"></span></p>
<p><a href='http://static.sjinks.info/wp-content/uploads/2011/02/der_generator.php_.diff'>Патч для BezahlCode-Generator 1.0</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p89028">
        <div class="code diff" id="p890code28">
--- der_generator.orig.php&nbsp; 2011-02-09 04:52:27.000000000 +0200<br />
<span class="re4">+++ der_generator.php &nbsp; <span class="nu0">2011</span>-02-09 05:00:<span class="nu0">20.457537559</span> +0200</span><br />
<span class="re6">@@ -<span class="nu0">16</span>,<span class="nu0">15</span> +<span class="nu0">16</span>,<span class="nu0">15</span> @@</span><br />
&nbsp;&lt;label for=&quot;singlepaymentspende&quot;&gt;&lt;input type=&quot;radio&quot; id=&quot;singlepaymentspende&quot; name=&quot;gen_type&quot; value=&quot;singlepaymentspende&quot; &lt;?php if<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_type'<span class="br0">&#93;</span>==&quot;singlepaymentspende&quot;<span class="br0">&#41;</span> echo 'checked=&quot;checked&quot;'?&gt;/&gt; Spendenzahlung&lt;/label&gt;&lt;br /&gt;<br />
&nbsp;&lt;label for=&quot;singledirectdebit&quot;&gt;&lt;input type=&quot;radio&quot; id=&quot;singledirectdebit&quot; name=&quot;gen_type&quot; value=&quot;singledirectdebit&quot; &lt;?php if<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_type'<span class="br0">&#93;</span>==&quot;singledirectdebit&quot;<span class="br0">&#41;</span> echo 'checked=&quot;checked&quot;'?&gt;/&gt; Lastschrift&lt;/label&gt;&lt;br /&gt;<br />
&nbsp;<br />
<span class="re7">-Name:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: DTAUS Text&quot; id=&quot;gen_name&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dtaus'<span class="br0">&#41;</span>&quot; name=&quot;gen_name&quot; maxlength=&quot;<span class="nu0">27</span>&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_name'<span class="br0">&#93;</span><span class="br0">&#41;</span>?$_REQUEST<span class="br0">&#91;</span>'gen_name'<span class="br0">&#93;</span>:&quot;&quot;?&gt;&quot;&gt;</span><br />
<span class="re8">+Name:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: DTAUS Text&quot; id=&quot;gen_name&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dtaus'<span class="br0">&#41;</span>&quot; name=&quot;gen_name&quot; maxlength=&quot;<span class="nu0">27</span>&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_name'<span class="br0">&#93;</span><span class="br0">&#41;</span>?esc_attr<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_name'<span class="br0">&#93;</span><span class="br0">&#41;</span>:&quot;&quot;?&gt;&quot;&gt;</span><br />
&nbsp;&lt;br /&gt;<br />
<span class="re7">-Kontonummer:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Ganzzahl z.B. <span class="nu0">1234</span>&quot; id=&quot;gen_account&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'ganzzahl'<span class="br0">&#41;</span>&quot; name=&quot;gen_account&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_account'<span class="br0">&#93;</span><span class="br0">&#41;</span>?$_REQUEST<span class="br0">&#91;</span>'gen_account'<span class="br0">&#93;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
<span class="re8">+Kontonummer:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Ganzzahl z.B. <span class="nu0">1234</span>&quot; id=&quot;gen_account&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'ganzzahl'<span class="br0">&#41;</span>&quot; name=&quot;gen_account&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_account'<span class="br0">&#93;</span><span class="br0">&#41;</span>?esc_attr<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_account'<span class="br0">&#93;</span><span class="br0">&#41;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
&nbsp;&lt;br /&gt;<br />
<span class="re7">-BLZ:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Ganzzahl z.B. <span class="nu0">1234</span>&quot; id=&quot;gen_BNC&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'ganzzahl'<span class="br0">&#41;</span>&quot; name=&quot;gen_BNC&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_BNC'<span class="br0">&#93;</span><span class="br0">&#41;</span>?$_REQUEST<span class="br0">&#91;</span>'gen_BNC'<span class="br0">&#93;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
<span class="re8">+BLZ:&lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Ganzzahl z.B. <span class="nu0">1234</span>&quot; id=&quot;gen_BNC&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'ganzzahl'<span class="br0">&#41;</span>&quot; name=&quot;gen_BNC&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_BNC'<span class="br0">&#93;</span><span class="br0">&#41;</span>?esc_attr<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_BNC'<span class="br0">&#93;</span><span class="br0">&#41;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
&nbsp;&lt;br /&gt;<br />
<span class="re7">-Betrag in Euro <span class="br0">&#40;</span>z.B. <span class="nu0">1234</span>,<span class="nu0">50</span><span class="br0">&#41;</span> &lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Dezimalzahl z.B. <span class="nu0">1234</span>,<span class="nu0">50</span>&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dezimalzahl'<span class="br0">&#41;</span>&quot; id=&quot;gen_amount&quot; name=&quot;gen_amount&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_amount'<span class="br0">&#93;</span><span class="br0">&#41;</span>?$_REQUEST<span class="br0">&#91;</span>'gen_amount'<span class="br0">&#93;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
<span class="re8">+Betrag in Euro <span class="br0">&#40;</span>z.B. <span class="nu0">1234</span>,<span class="nu0">50</span><span class="br0">&#41;</span> &lt;br /&gt;&lt;input type=&quot;text&quot; tooltipText=&quot;Format: Dezimalzahl z.B. <span class="nu0">1234</span>,<span class="nu0">50</span>&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dezimalzahl'<span class="br0">&#41;</span>&quot; id=&quot;gen_amount&quot; name=&quot;gen_amount&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_amount'<span class="br0">&#93;</span><span class="br0">&#41;</span>?esc_attr<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_amount'<span class="br0">&#93;</span><span class="br0">&#41;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
&nbsp;&lt;br /&gt;<br />
<span class="re7">-Verwendungszweck:&lt;br /&gt;&lt;input type=&quot;text&quot; id=&quot;gen_reason&quot; tooltipText=&quot;Format: DTAUS Text&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dtaus'<span class="br0">&#41;</span>&quot; name=&quot;gen_reason&quot; maxlength=&quot;<span class="nu0">54</span>&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_reason'<span class="br0">&#93;</span><span class="br0">&#41;</span>?$_REQUEST<span class="br0">&#91;</span>'gen_reason'<span class="br0">&#93;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
<span class="re8">+Verwendungszweck:&lt;br /&gt;&lt;input type=&quot;text&quot; id=&quot;gen_reason&quot; tooltipText=&quot;Format: DTAUS Text&quot; onblur=&quot;checkInput<span class="br0">&#40;</span>this, 'dtaus'<span class="br0">&#41;</span>&quot; name=&quot;gen_reason&quot; maxlength=&quot;<span class="nu0">54</span>&quot; value=&quot;&lt;?= isset<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_reason'<span class="br0">&#93;</span><span class="br0">&#41;</span>?esc_attr<span class="br0">&#40;</span>$_REQUEST<span class="br0">&#91;</span>'gen_reason'<span class="br0">&#93;</span><span class="br0">&#41;</span>:&quot;&quot;?&gt;&quot; &gt;</span><br />
&nbsp;&lt;br/&gt;<br />
&nbsp;&lt;input type=&quot;button&quot; value=&quot;Erstellen&quot; onclick='javascript:generateImage<span class="br0">&#40;</span><span class="br0">&#41;</span>;'&gt;<br />
&nbsp;&lt;/form&gt;
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/890-bezahlcode-generator-xss/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/890-bezahlcode-generator-xss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPress, поиск и кириллица</title>
		<link>http://blog.sjinks.pro/wordpress/881-wordpress-search-cyrillic/</link>
		<comments>http://blog.sjinks.pro/wordpress/881-wordpress-search-cyrillic/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 14:11:53 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[ошибка]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=881</guid>
		<description><![CDATA[Правильные результаты поиска при использовании красивых ссылок Есть у WordPress одна неприятная особенность: при использовании красивых ссылок и их использовании при поиске кириллических (или любых не-ASCII) слов получается совсем не тот результат, который ожидается. Например, есть такая ссылка: http://blog.sjinks.pro/search/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F/ %D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F — это слово «Генерация», закодированное функцией urlencode(). Ожидается, что WordPress будет искать статьи со словом «генерация». Но, [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/881-wordpress-search-cyrillic/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Правильные результаты поиска при использовании красивых ссылок</em></h2>
<p>Есть у <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> одна неприятная особенность: при использовании <abbr title="permalinks">красивых ссылок</abbr> и их использовании при поиске кириллических (или любых не-ASCII) слов получается совсем не тот результат, который ожидается.</p>
<p>Например, есть такая ссылка:</p>
<p><a href="http://blog.sjinks.pro/search/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F/">http://blog.sjinks.pro/search/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F/</a></p>
<p><code>%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F</code> — это слово «Генерация», закодированное функцией <code>urlencode()</code>.</p>
<p>Ожидается, что WordPress будет искать статьи со словом «генерация». Но, так как разработчики WordPress — американцы, они не предполагают, что существуют буквы кроме английских <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Собственно, эта беда свойственна многим проектам с англоязычными авторами. Итак…<span id="more-881"></span></p>
<p>Проблема заключается в том, что WordPress выдаёт разные результаты для двух казалось бы идентичных запросов:</p>
<ol>
<li><strong>«Традиционный поиск» — без использования красивых ссылок</strong>:<br />
<a href="http://blog.sjinks.pro/?s=%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F">http://blog.sjinks.pro/?s=%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F</a><br />
<a href="http://static.sjinks.info/wp-content/uploads/2011/01/search-no-permalinks.png"><img src="http://static.sjinks.info/wp-content/uploads/2011/01/search-no-permalinks.png" alt="Поиск — без использования красивых ссылок" title="Поиск — без использования красивых ссылок" width="446" height="153" class="alignnone size-full wp-image-882" /></a></li>
<li><strong>Поиск с использованием красивых ссылок</strong>:<br />
<a href="http://blog.sjinks.pro/search/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F/">http://blog.sjinks.pro/search/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F/</a><br />
<a href="http://static.sjinks.info/wp-content/uploads/2011/01/search-permalinks.png"><img src="http://static.sjinks.info/wp-content/uploads/2011/01/search-permalinks.png" alt="Поиск с использованием красивых ссылок" title="Поиск с использованием красивых ссылок" width="439" height="267" class="alignnone size-full wp-image-883" /></a></li>
</ol>
<p>В первом случае WordPress вернул 6 результатов, во втором — только один. При этом в первом случае искомое слово отображается правильно, во втором — нет.</p>
<p>Если посмотреть на запросы при помощи <a href="http://blog.sjinks.pro/wordpress-plugins/sqlmon/">плагина SQLMon</a>, увидим такую картину: в первом случае запрос имеет вид</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88132">
        <div class="code mysql" id="p881code32">
<span class="kw1">SELECT</span> <span class="kw1">SQL_CALC_FOUND_ROWS</span> wp_posts.<span class="sy1">*</span><br />
<span class="kw1">FROM</span> wp_posts <br />
<span class="kw1">WHERE</span> 1<span class="sy1">=</span>1 <br />
&nbsp; &nbsp; <span class="kw10">AND</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>wp_posts.post_title <span class="kw10">LIKE</span> <span class="st0">'<span class="es1">%</span>Генерация<span class="es1">%</span>'</span><span class="br0">&#41;</span> <span class="kw10">OR</span> <span class="br0">&#40;</span>wp_posts.post_content <span class="kw10">LIKE</span> <span class="st0">'<span class="es1">%</span>Генерация<span class="es1">%</span>'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw10">AND</span> wp_posts.post_type <span class="kw2">IN</span> <span class="br0">&#40;</span><span class="st0">'post'</span><span class="sy2">,</span> <span class="st0">'page'</span><span class="sy2">,</span> <span class="st0">'attachment'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw10">AND</span> <span class="br0">&#40;</span>wp_posts.post_status <span class="sy1">=</span> <span class="st0">'publish'</span> <span class="kw10">OR</span> wp_posts.post_status <span class="sy1">=</span> <span class="st0">'private'</span><span class="br0">&#41;</span><br />
<span class="kw1">ORDER BY</span> wp_posts.post_date <span class="kw1">DESC</span><br />
<span class="kw1">LIMIT</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">10</span>
        </div>
    </div>
</div>

<p>Во втором случае запрос выглядит страшнее:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88133">
        <div class="code mysql" id="p881code33">
<span class="kw1">SELECT</span> <span class="kw1">SQL_CALC_FOUND_ROWS</span> wp_posts.<span class="sy1">*</span><br />
<span class="kw1">FROM</span> wp_posts<br />
<span class="kw1">WHERE</span> 1<span class="sy1">=</span>1<br />
&nbsp; &nbsp; <span class="kw10">AND</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>wp_posts.post_title <span class="kw10">LIKE</span> <span class="st0">'<span class="es1">%</span><span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>93<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B5<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>BD<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B5<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>80<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B0<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>86<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B8<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>8F<span class="es1">%</span>'</span><span class="br0">&#41;</span> <span class="kw10">OR</span> <span class="br0">&#40;</span>wp_posts.post_content <span class="kw10">LIKE</span> <span class="st0">'<span class="es1">%</span><span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>93<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B5<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>BD<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B5<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>80<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B0<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>86<span class="es0">\\</span><span class="es1">%</span>D0<span class="es0">\\</span><span class="es1">%</span>B8<span class="es0">\\</span><span class="es1">%</span>D1<span class="es0">\\</span><span class="es1">%</span>8F<span class="es1">%</span>'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw10">AND</span> wp_posts.post_type <span class="kw2">IN</span> <span class="br0">&#40;</span><span class="st0">'post'</span><span class="sy2">,</span> <span class="st0">'page'</span><span class="sy2">,</span> <span class="st0">'attachment'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw10">AND</span> <span class="br0">&#40;</span>wp_posts.post_status <span class="sy1">=</span> <span class="st0">'publish'</span> <span class="kw10">OR</span> wp_posts.post_status <span class="sy1">=</span> <span class="st0">'private'</span><span class="br0">&#41;</span><br />
<span class="kw1">ORDER BY</span> wp_posts.post_date <span class="kw1">DESC</span><br />
<span class="kw1">LIMIT</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">10</span>
        </div>
    </div>
</div>

<p>Создаётся впечатление, что WordPress забыл выполнить <code>urldecode()</code>. Вполне вероятно, что этим никто и не озадачивался: при передаче параметров через строку запроса (как в первом случае) ответственность за перевод значений в «читаемую форму» лежит на <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>. А во втором случае закодированное значение является частью URI, поэтому <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> его не трогает.</p>
<p>Решение тривиально: в файл <code>functions.php</code> темы нужно добавить такой код (можно оформить плагином, но банально лень):</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88134">
        <div class="code php" id="p881code34">
&nbsp; &nbsp; <span class="kw2">function</span> my_request<span class="br0">&#40;</span><span class="re0">$vars</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$wp_rewrite</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$wp_rewrite</span><span class="sy0">-&gt;</span><span class="me1">using_permalinks</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$vars</span><span class="br0">&#91;</span><span class="st_h">'s'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st_h">'s'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$vars</span><span class="br0">&#91;</span><span class="st_h">'s'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw3">urldecode</span><span class="br0">&#40;</span><span class="re0">$vars</span><span class="br0">&#91;</span><span class="st_h">'s'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$vars</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; add_filter<span class="br0">&#40;</span><span class="st_h">'request'</span><span class="sy0">,</span> <span class="st_h">'my_request'</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Хак применяется и на этом блоге, поэтому приведённые скриншоты более не воспроизводимы.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/881-wordpress-search-cyrillic/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/881-wordpress-search-cyrillic/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Capital P, Dang It!</title>
		<link>http://blog.sjinks.pro/wordpress/879-capital-p-dang-it/</link>
		<comments>http://blog.sjinks.pro/wordpress/879-capital-p-dang-it/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 03:11:33 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[плагин]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=879</guid>
		<description><![CDATA[Цензура в WordPress Пару недель назад я заметил интересную особенность в WordPress: он автоматически заменяет Wordpress на WordPress. Как оказалось, такое поведение существует в WordPress где-то с версии 3.0. Со временем приоритет фильтра замены изменился; что характерно, оба эти изменения прошли совершенно незаметно — не было никакого обсуждения в Trac. Что мне не нравится, так это отсутствие «изкоробочной» [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/879-capital-p-dang-it/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Цензура в <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a></em></h2>
<p>Пару недель назад я заметил интересную особенность в WordPress: он автоматически заменяет Wordpress на WordPress. <a href="http://core.trac.wordpress.org/changeset/14996" rel="nofollow">Как</a> <a href="http://justintadlock.com/archives/2010/07/08/lowercase-p-dangit">оказалось</a>, такое поведение существует в WordPress где-то с версии 3.0. <a href="http://core.trac.wordpress.org/changeset/15877" rel="nofollow">Со временем</a> приоритет фильтра замены изменился; что характерно, оба эти изменения прошли совершенно незаметно — не было никакого обсуждения в Trac.<span id="more-879"></span></p>
<p>Что мне не нравится, так это отсутствие «изкоробочной» возможности отключить такое поведение. Я очень не люблю, когда система считает себя умнее пользователя <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Как это убрать:</strong> можно добавить этот код в <code>functions.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code> используемой темы:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87936">
        <div class="code php" id="p879code36">
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">function_exists</span><span class="br0">&#40;</span><span class="st_h">'add_action'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">:</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">function</span> mytheme_init<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'the_content'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'the_title'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'comment_text'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'the_content'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="sy0">,</span> 11<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'the_title'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="sy0">,</span> 11<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; remove_filter<span class="br0">&#40;</span><span class="st_h">'comment_text'</span><span class="sy0">,</span> <span class="st_h">'capital_P_dangit'</span><span class="sy0">,</span> 31<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; add_action<span class="br0">&#40;</span><span class="st_h">'init'</span><span class="sy0">,</span> <span class="st_h">'mytheme_init'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw1">endif</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Желающие могут воспользоваться плагином <a href="http://wordpress.org/extend/plugins/remove-wordpress-to-wordpress-filter">Remove Wordpress to WordPress Filter</a>, но он не убирает фильтр с <code>comment_text</code> для WordPress 3.0.1 и выше.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/879-capital-p-dang-it/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/879-capital-p-dang-it/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress: кэширование средствами nginx</title>
		<link>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/</link>
		<comments>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 12:08:15 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[кэш]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=877</guid>
		<description><![CDATA[Уменьшение потребления ресурсов во много раз Много было сказано про кэширование в WordPress… Сегодня я хочу рассказать о действительно эффективном методе, позволяющем сильно снизить нагрузку. Метод основан на использовании кэша FastCGI web-сервера nginx. Идея состоит в генерации статических страниц и отдачи их пользователям, не имеющим cookie комментатора. Зарегистрированным пользователям, а также комментаторам всегда отдаётся свежая [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Уменьшение потребления ресурсов во много раз</em></h2>
<p>Много было сказано про <a href="http://blog.sjinks.pro/?s=WordPress%20cache">кэширование в WordPress</a>… Сегодня я хочу рассказать о действительно эффективном методе, позволяющем сильно снизить нагрузку.</p>
<p>Метод основан на использовании кэша <a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">FastCGI</a> web-сервера <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>.</p>
<p>Идея состоит в генерации статических страниц и отдачи их пользователям, не имеющим cookie комментатора. Зарегистрированным пользователям, а также комментаторам всегда отдаётся свежая страница. Так как читателей, ни разу не оставлявших комментарий, как правило, гораздо больше, чем комментаторов, то подобный использование кэша позволяет значительно снизить нагрузку на <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>/<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>. Знакомые с принципом работы WP Super Cache заметят, что WPSC использует тот же принцип работы.<span id="more-877"></span></p>
<p>В чем же преимущество перекладывания работы на Web-сервер (nginx)?</p>
<ol>
<li>PHP — интерпретируемый язык. Как следствие, аналогичный код на компилируемом языке будет во много раз быстрее.</li>
<li>WordPress во многом bloatware <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  От момента начала загрузки страницы до окончания выполнения стадии <code>init</code> выполняется очень много «лишнего» кода.</li>
<li>В зависимости от нагрузки на сервер от запроса страницы до выполнения PHP-кода может пройти некоторое время: всё зависит от загруженности PHP (если все дочерние процессы PHP заняты обработкой запроса, новому запросу придётся ждать освобождения одного из процессов. Если за приемлемое время ни один процесс не освободился, пользователь видит сообщение о печально знаменитой ошибке 504).</li>
<li>Когда обслуживанием кэша занимается web-сервер, шансы на возникновение <a href="http://blog.sjinks.pro/wordpress/521-wp-super-cache-under-high-load/">подобной ситуации</a></li>
 (когда даже автор не может понять, в чём дело) значительно снижаются: реализация синхронизации/блокировок средствами PHP — неблагодарное дело.
</ol>
<p>Теперь переходим от теории к практике.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87739">
        <div class="code nginx" id="p877code39">
<ol class="nginx" style="font-family:monospace;"><li class="li1"><div class="de1"><span class="kw1">fastcgi_cache_path</span> /var/lib/nginx/myblog levels=2 keys_zone=myblog:10m max_size=512m inactive=20m;</div></li>
<li class="li1"><div class="de1"><span class="kw1">server</span> {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">server_name</span> example.com;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">root</span> /path/to/blog;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> ($http_cookie ~* <span class="st0">&quot;comment_author_|wordpress_(?!test_cookie)|wp-postpass_&quot;</span> ) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $do_not_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; fastcgi_cache_bypass $do_not_cache;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; fastcgi_no_cache $do_not_cache;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_pass_header</span> Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache</span> myblog;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_key</span> $request_method|$host|$request_uri;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 301 8h;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 404 1h;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 200 15m;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> ($http_user_agent !~ FeedBurner) {</div></li>
<li class="li1"><div class="de1"><span class="co1"># Здесь идут перенаправления для FeedBurner</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">error_page</span> 404 = @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">log_not_found</span> <span class="kw2">off</span>;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ^~ /files/ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> /files/(.+) /wp-includes/ms-files.php?file=$1 last;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ~ ^/(wp-admin/.*\.php|wp-login\.php|wp-register\.php|(feed|comment/feed)(/.*)?)$ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try_files</span> $uri @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $do_not_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_cache_bypass <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_no_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> @wordpress {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_NAME /<span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root/<span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ($do_not_cache != <span class="st0">&quot;1&quot;</span>) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add_header</span> Vary Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ~ \.php$ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try_files</span> $uri @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ($do_not_cache != <span class="st0">&quot;1&quot;</span>) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add_header</span> Vary Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ^~ /blogs.dir/ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">internal</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">root</span> /path/to/blog/wp-content/;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">}</div></li>
</ol>
        </div>
    </div>
</div>

<p>Документация по использованию FastCGI в nginx приведена <a href="http://sysoev.ru/nginx/docs/http/ngx_http_fastcgi_module.html">здесь</a>, поэтому я не буду подробно останавливаться на том, что конкретно каждая директива делает.</p>
<p>Основная магия происходит в строка 8—10: здесь определяются условия, при которых отдаётся свежая страница. В данном случае проверяется наличие авторизационных cookie и cookie комментатора. Важно, чтобы в случае отказа от кэширования переменная $<code>do_not_cache</code> устанавливалась в 1.</p>
<p>Строка 16 задаёт ключ, по которому страница доступна в кэше. В ключе присутствует <code>$request_method</code>, чтобы различать запросы GET и HEAD (для HEAD данные не возвращаются, только заголовки).</p>
<p>Строки 17—19 задают время жизни кэша в зависимости от кода ответа. Чем больше время жизни, тем реже будет обновляться информация для незарегистрированных пользователей.</p>
<p>В строке 32 задаётся маска для страниц, которые не должны кэшироваться (например, админка, страницы логина и регистрации, фиды).</p>
<p>Так как содержимое страницы <em>может</em> отличаться в зависимости от cookie пользователя, в строках 49 и 59 для закэшированных страниц принудительно выставляется заголовок <code>Vary: Cache</code>. Если используются другие правила (например, фильтрация по User-Agent), нужно добавлять соответствующее правило.</p>
<p>Строки 21—23: подробнее описано в статье <strong>«<a href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/">Перенаправление RSS в WordPress на FeedBurner для nginx</a>»</strong></p>
<p>Строки 28—30, 63—66 подробнее описаны в статье <strong>«<a href="http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/">WordPress MultiSite, nginx и X-Accel-Redirect</a>»</strong></p>
<p>Вроде бы ничего не забыл. Теперь о том, какую <a href="http://blog.sjinks.pro/tag/performance/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  производительность">производительность</a> мы получаем:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87740">
        <div class="code text" id="p877code40">
$ ab -n 10000 -c 100 http://blog.sjinks.pro/<br />
Server Software: &nbsp; &nbsp; &nbsp; &nbsp;nginx<br />
Server Hostname: &nbsp; &nbsp; &nbsp; &nbsp;blog.sjinks.pro<br />
Server Port: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;80<br />
<br />
Document Path: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/<br />
Document Length: &nbsp; &nbsp; &nbsp; &nbsp;50294 bytes<br />
<br />
Concurrency Level: &nbsp; &nbsp; &nbsp;100<br />
Time taken for tests: &nbsp; 46.925 seconds<br />
Complete requests: &nbsp; &nbsp; &nbsp;10000<br />
Failed requests: &nbsp; &nbsp; &nbsp; &nbsp;0<br />
Write errors: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0<br />
Total transferred: &nbsp; &nbsp; &nbsp;504940000 bytes<br />
HTML transferred: &nbsp; &nbsp; &nbsp; 502940000 bytes<br />
Requests per second: &nbsp; &nbsp;213.10 [#/sec] (mean)<br />
Time per request: &nbsp; &nbsp; &nbsp; 469.254 [ms] (mean)<br />
Time per request: &nbsp; &nbsp; &nbsp; 4.693 [ms] (mean, across all concurrent requests)<br />
Transfer rate: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10508.28 [Kbytes/sec] received<br />
<br />
Connection Times (ms)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; min &nbsp;mean[+/-sd] median &nbsp; max<br />
Connect: &nbsp; &nbsp; &nbsp; 16 &nbsp; 94 &nbsp;76.9 &nbsp; &nbsp; 94 &nbsp; &nbsp;3125<br />
Processing: &nbsp; 118 &nbsp;373 &nbsp;81.7 &nbsp; &nbsp;360 &nbsp; &nbsp;1334<br />
Waiting: &nbsp; &nbsp; &nbsp; 17 &nbsp; 69 &nbsp;38.5 &nbsp; &nbsp; 57 &nbsp; &nbsp; 422<br />
Total: &nbsp; &nbsp; &nbsp; &nbsp;156 &nbsp;467 105.0 &nbsp; &nbsp;445 &nbsp; &nbsp;3535<br />
<br />
Percentage of the requests served within a certain time (ms)<br />
&nbsp; 50% &nbsp; &nbsp;445<br />
&nbsp; 66% &nbsp; &nbsp;454<br />
&nbsp; 75% &nbsp; &nbsp;471<br />
&nbsp; 80% &nbsp; &nbsp;494<br />
&nbsp; 90% &nbsp; &nbsp;541<br />
&nbsp; 95% &nbsp; &nbsp;589<br />
&nbsp; 98% &nbsp; &nbsp;655<br />
&nbsp; 99% &nbsp; &nbsp;768<br />
&nbsp;100% &nbsp; 3535 (longest request)
        </div>
    </div>
</div>

<p>Сервер зафлудили 10,000 запросами в 100 <strong>параллельных</strong> потоков. Сервер выдал практически полгигабайта за 47 секунд; в среднем сервер обрабатывал <strong>213 запросов в секунду</strong>, при этом <strong>99% запросов были обработаны за 768 мс</strong> (при том, что на сервере несколько сайтов в Alexa Top 100,000)! Нагрузка на сервер была минимальной (изменений Load Average замечено не было).</p>
<p><strong style="color: red">UPDATE:</strong> есть один небольшой нюанс: CAPTCHA. Если вы их используете, убедитесь, что они работают. Дело в том, что страница со статьёй будет отдаваться непосредственно из кэша nginx, PHP загружаться не будет. Поэтому если CAPTCHA полагается на использование сессии, она может работать неправильно. Здесь всё зависит от используемого плагина.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
	</channel>
</rss>

