<?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>AskApache &#187; WordPress Plugins</title>
	<atom:link href="http://www.askapache.com/wordpress-plugins/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.askapache.com</link>
	<description>Advanced Web Development</description>
	<lastBuildDate>Thu, 19 Nov 2009 12:21:49 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Advanced WordPress wp-config.php Tweaks</title>
		<link>http://www.askapache.com/wordpress/advanced-wp-config-php-tweaks.html</link>
		<comments>http://www.askapache.com/wordpress/advanced-wp-config-php-tweaks.html#comments</comments>
		<pubDate>Sat, 03 Oct 2009 07:23:37 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Linux Unix BSD]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Server Administration]]></category>
		<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[Webmaster]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[advanced]]></category>
		<category><![CDATA[Cookies]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[phpinfo]]></category>
		<category><![CDATA[wp-config.php]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=3341</guid>
		<description><![CDATA[<p>The bottom line for this article is that I want to make WordPress as fast, secure, and easy to install, run, and manage because I am using it more and more for client production sites, I will work for days in order to solve an issue so that I never have to spend time on that issue again. Time is money in this industry and that is ultimately (time) what there is to gain by tweaking WordPress.</p>

<p class="cnote"><strong>Note:</strong> I spent no time on readability, this is primarily a read the code and figure it out article.. This is for advanced users looking for a reference or discussion and for those of you looking to advance.  Feedback would be great <em>if you make it that far..</em></p>]]></description>
			<content:encoded><![CDATA[<p>The bottom line for this article is that I want to make WordPress as fast, secure, and easy to install, run, and manage because I am using it more and more for client production sites, I will work for days in order to solve an issue so that I never have to spend time on that issue again. Time is money in this industry and that is ultimately (time) what there is to gain by tweaking WordPress.</p>
<p class="cnote"><strong>Note:</strong> I spent no time on readability, this is primarily a read the code and figure it out article.. This is for advanced users looking for a reference or discussion and for those of you looking to advance.  Feedback would be great <em>if you make it that far..</em></p>
<p>For a better handle on the way I like to structure web site directories, see <a href="http://www.askapache.com/htaccess/optimize-website-files-cache-security.html">Optimize a Website for Speed, Security, and Easy Management</a> but note it is a bit outdated compared to what I&#8217;m doing now.  I don&#8217;t have the luxury of using only one type of server, or hosting provider anymore, so I have been working towards making things even more portable in order to move from host to host from server to server without issues i.e. my portable <a href="http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html">.bash_profile</a>.</p>
<p>So I&#8217;ve been basically experimenting various ways to accomplish that and thought I would share what I am currently doing for my benefit and hopefully get some input.  All of my WP installs run the development version, and one main idea with my setups is that upgrading is automated.  So I really keep the WordPress install clean and use plugins and wp-config.php to do all the customization.</p>
<ul>
<li>Portability &#8211; Hands-free upgrades and easy to move</li>
<li>Security &#8211; Additional security and protection</li>
<li>Speed &#8211; Less CPU and Disk I/O</li>
<li>Customization &#8211; All my favorite customizations</li>
</ul>
<h2>wp-config.php</h2>
<p>These are the main settings I use.. Seriously this is more like an interactive article, because to understand it you will need to do some code grepping.  You may want to grab a jolt.</p>
<h3>ASKAPACHE_ROOT</h3>
<p>The ASKAPACHE_ROOT variable is just a better way for me to be able to include and access all the different files in my site tree.  For instance, in my non-wp php files, I can do this:</p>
<pre>
!defined(&#039;ASKAPACHE_ROOT&#039;) &#038;&#038; require $_SERVER[&#039;DOCUMENT_ROOT&#039;] . &#039;/wp-config.php&#039;;
include(ASKAPACHE_ROOT . &#039;/includes/custom-download.inc.php&#039;);
</pre>
<h3>ASKAPACHE_LOCK</h3>
<p>This is one of my all-time favorite hacks, that I think is one of the most useful methods I employ as a web developer.  This allows me to use far-future-expire headers for optimum caching, while still forcing browsers to re-validate every day or so automatically, or forcing them to re-validate whenever I change the suffix.  This takes advantage of the <a href="http://www.askapache.com/htaccess/mod_rewrite-fix-for-caching-updated-files.html">mod_rewrite trick</a> that I use on EVERY site I run, definately worth learning. Because I practice best-practice web-standards, for every web site I create a single css file and javascript file, which I then add to the template like:</p>
<pre>
&lt;link rel="stylesheet" type="text/css" media="all" href="http://z.askapache.com/c/apache-0&lt;?php echo ASKAPACHE_LOCK?&gt;.css" /&gt;
&lt;script src="http://z.askapache.com/j/apache-0&lt;?php echo ASKAPACHE_LOCK;?&gt;.js" type="text/javascript"&gt;&lt;/script&gt;
</pre>
<pre>
&lt;?php
/**
 * The base configurations of the WordPress.
 *
 * This file has the following configurations: MySQL settings, Table Prefix,
 * Secret Keys, WordPress Language, and ABSPATH. You can find more information by
 * visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing
 * wp-config.php} Codex page. You can get the MySQL settings from your web host.
 *
 * This file is used by the wp-config.php creation script during the
 * installation. You don&#039;t have to use the web site, you can just copy this file
 * to "wp-config.php" and fill in the values.
 *
 * @package WordPress
 */
/* http://codex.wordpress.org/Editing_wp-config.php */
&nbsp;
/** /home/liet/askapache.com */
!defined(&#039;ASKAPACHE_ROOT&#039;) &#038;&#038; define(&#039;ASKAPACHE_ROOT&#039;, str_replace(&#039;/htdocs&#039;,&#039;&#039;, $_SERVER[&#039;DOCUMENT_ROOT&#039;]));
&nbsp;
/** The 008 at the end is for manual tweaking.  time() returns seconds since &#039;00:00:00 1970-01-01 UTC&#039;. */
// http://www.askapache.com/htaccess/mod_rewrite-fix-for-caching-updated-files.html
!defined(&#039;ASKAPACHE_LOCK&#039;) &#038;&#038; define(ASKAPACHE_LOCK&#039;, substr(time(),0,5).&#039;008&#039;); // 12533001
&nbsp;
/** absolute path to the Wordpress directory */
!defined(&#039;ABSPATH&#039;) &#038;&#038; define(&#039;ABSPATH&#039;, ASKAPACHE_ROOT .&#039;/htdocs/&#039;);
&nbsp;
/**
 * WP_SITEURL, defined since WordPress Version 2.2, allows the WordPress address (URL) to be defined. The valued defined is the address where your WordPress core files reside.
 * It should include the http:// part too. Do not put a slash "/" at the end.
 * Setting this value in wp-config.php overrides the wp_options table value for siteurl and disables the WordPress address (URL) field in the Administration &gt; Settings &gt; General panel.
 */
!defined(&#039;WP_SITEURL&#039;) &#038;&#038; define(&#039;WP_SITEURL&#039;, &#039;http://&#039;.$_SERVER[&#039;SERVER_NAME&#039;]);
&nbsp;
/**
 * WP_HOME is another wp-config.php option added in WordPress Version 2.2. Similar to WP_SITEURL,
 * WP_HOME overrides the wp_options table value for home but does not change it permanently.
 * home is the address you want people to type in their browser to reach your WordPress blog. It should include the http:// part. Also, do not put a slash "/" at the end.
 */
!defined(&#039;WP_HOME&#039;) &#038;&#038; define(&#039;WP_HOME&#039;, WP_SITEURL);
&nbsp;
/** no trailing slash, full paths only */
!defined(&#039;WP_CONTENT_DIR&#039;) &#038;&#038; define( &#039;WP_CONTENT_DIR&#039;, ABSPATH . &#039;wp-content&#039; );
&nbsp;
// full url - WP_CONTENT_DIR is defined further up
!defined(&#039;WP_CONTENT_URL&#039;) &#038;&#038; define( &#039;WP_CONTENT_URL&#039;, WP_SITEURL . &#039;/wp-content&#039;);
&nbsp;
/** Allows for the plugins directory to be moved from the default location. @since 2.6.0 */
// full path, no trailing slash
!defined(&#039;WP_PLUGIN_DIR&#039;) &#038;&#038; define( &#039;WP_PLUGIN_DIR&#039;, WP_CONTENT_DIR . &#039;/plugins&#039; );
&nbsp;
/** Allows for the plugins directory to be moved from the default location. @since 2.6.0 */
// full url, no trailing slash
!defined(&#039;WP_PLUGIN_URL&#039;) &#038;&#038; define( &#039;WP_PLUGIN_URL&#039;, WP_CONTENT_URL . &#039;/plugins&#039; );
&nbsp;
/** Allows for the plugins directory to be moved from the default location. @since 2.1.0 */
// Relative to ABSPATH.  For back compat.
//!defined(&#039;PLUGINDIR&#039;) &#038;&#038; define( &#039;PLUGINDIR&#039;, &#039;wp-content/plugins&#039; );
&nbsp;
/** Number of autosaves to save. TRUE is default and enables post revisions, FALSE disables revisions completely. */
!defined(&#039;WP_POST_REVISIONS&#039;) &#038;&#038; define(&#039;WP_POST_REVISIONS&#039;, 150);
&nbsp;
/* ini_set(&#039;memory_limit&#039;, WP_MEMORY_LIMIT); */
!defined(&#039;WP_MEMORY_LIMIT&#039;) &#038;&#038; define(&#039;WP_MEMORY_LIMIT&#039;, &#039;64M&#039;);
&nbsp;
/** Only check at this interval for new messages. Default is 5min */
/** @since 2.9  */
!defined(&#039;WP_MAIL_INTERVAL&#039;) &#038;&#038; define(&#039;WP_MAIL_INTERVAL&#039;, 3600); // 1 hour
&nbsp;
/** Saves updated post values to post from edit window every x seconds. (default 60)
 * When editing a post, WordPress uses Ajax to auto-save revisions to the post as you edit. You may want to increase this setting for longer delays in between auto-saves, or decrease the setting to make sure you never lose changes.
 * @since 2.5.0 */
!defined( &#039;AUTOSAVE_INTERVAL&#039; ) &#038;&#038; define( &#039;AUTOSAVE_INTERVAL&#039;, 60 );
&nbsp;
/** @since 2.9.0  */
/** Permanently deletes posts, pages, attachments, and comments which have been in the trash for EMPTY_TRASH_DAYS. */
!defined( &#039;EMPTY_TRASH_DAYS&#039; ) &#038;&#038; define( &#039;EMPTY_TRASH_DAYS&#039;, 300 );
</pre>
<hr class="C" />
<h2>Debugging WordPress</h2>
<p>One of my secrets for getting really good at this stuff is to master debugging.  There is really not ever a time when I am working on a site that I don&#8217;t have <a href="http://www.askapache.com/security/elite-log-file-scrolling-with-color-syntax.html">color-highlighted logs scrolling automatically in an ssh window</a>.  It&#8217;s really almost impossible to fix problems with wordpress or do any kind of advanced anything without being able to view debugging info.  At first I relied heavily on a <a href="http://www.askapache.com/php/custom-phpini-tips-and-tricks.html">custom php.ini</a> being available on the server, but after having to deal with many hosts who don&#8217;t allow <code>php.ini</code> files I now rely completely on setting values using <a href="http://php.net/manual/en/function.ini-set.php">ini_set</a> for ultimate portability. Detailed towards the end of this article and is also included in this <code>wp-config.php</code></p>
<pre>
/**#@+
 * DEBUGGING STUFF
 */
/** display of notices during development. if false, error_reporting is E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR otherwise E_ALL */
!defined(&#039;WP_DEBUG&#039;) &#038;&#038; define(&#039;WP_DEBUG&#039;, false);
&nbsp;
/** The SAVEQUERIES definition saves the database queries to a array and that array can be displayed to help analyze those queries.
 *  The information saves each query, what function called it, and how long that query took to execute.  */
!defined(&#039;SAVE_QUERIES&#039;) &#038;&#038; define(&#039;SAVE_QUERIES&#039;, WP_DEBUG);
&nbsp;
!defined(&#039;ACTION_DEBUG&#039;) &#038;&#038; define(&#039;ACTION_DEBUG&#039;, WP_DEBUG);
&nbsp;
/** This will allow you to edit the scriptname.dev.js files in the wp-includes/js and wp-admin/js directories.  */
!defined(&#039;SCRIPT_DEBUG&#039;) &#038;&#038; define(&#039;SCRIPT_DEBUG&#039;, WP_DEBUG);

&nbsp;
/** Add define(&#039;WP_DEBUG_LOG&#039;, true); to enable php debug logging to WP_CONTENT_DIR/debug.log */
//!defined(&#039;WP_DEBUG_LOG&#039;) &#038;&#038; define(&#039;WP_DEBUG_LOG&#039;, true);
&nbsp;
/** This determines whether errors should be printed to the screen as part of the output or if they should be hidden from the user.
 *  Add define(&#039;WP_DEBUG_DISPLAY&#039;, false); to wp-config.php to use the globally configured setting for display_errors and not force it to On */
!defined(&#039;WP_DEBUG_DISPLAY&#039;) &#038;&#038; define(&#039;WP_DEBUG_DISPLAY&#039;, false);
</pre>
<hr class="C" />
<h2>Ultimate Security Tweaks</h2>
<p>Well, ultimate for WP&#8217;s built-in keys and password functions, this is all for wp-config.php keep in mind.  This is a very neccessary and recommended step, and is one of the only things I modify for each new installation.</p>
<h3>Security KEYS</h3>
<p>If like me you are familiar with password-cracking software like John the ripper, rainbow hash tables, l0pht-crack, etc.. then you will like to know that you can specify your own keys and salts for the encryption used by WP.  They are <code>AUTH_KEY</code>, <code>AUTH_SALT</code>, <code>SECURE_AUTH_KEY</code>, <code>SECURE_AUTH_SALT</code>, <code>LOGGED_IN_KEY</code>, <code>LOGGED_IN_SALT</code>, <code>NONCE_KEY</code>, <code>NONCE_SALT</code>,  <code>SECRET_KEY</code> and <code>SECRET_SALT</code>.</p>
<p>A random and long key gives you better encryption, and exponentially increasing that is using a random and long salt for the encryption.  Encryptions with known salts are incredibly easy to decrypt compared to encryptions with secure salts, because the salt + key individually need to be guessed in order to find a matching hash, vs. just the key if the salt is known.  See: <a href="http://www.askapache.com/security/locating-weak-passwords.html">Locating weak passwords</a>.</p>
<blockquote>
<p>A secret key is a hashing salt which makes your site harder to hack and access harder to crack by adding random elements to the password.</p>
<p>In simple terms, a secret key is a password with elements that make it harder to generate enough options to break through your security barriers. A password like &#8220;password&#8221; or &#8220;test&#8221; is simple and easily broken. A random, unpredictable password such as &#8220;88a7da62429ba6ad3cb3c76a09641fc&#8221; takes years to come up with the right combination.</p>
</blockquote>
<p>For more information on the technical background and breakdown of secret keys and secure passwords, see: </p>
<ul>
<li><a href="http://wordpress.org/support/topic/170987">WordPress Support Forum &#8211; HOWTO: Set up secret keys in WordPress 2.6+</a></li>
<li><a href="http://en.wikipedia.org/wiki/Password_cracking">Wikipedia&#8217;s explanation of Password Cracking</a></li>
</ul>
<p>I like to use the <a href="https://api.wordpress.org/secret-key/1.1/">WordPress.org secret-key service</a> 4 times.  That&#8217;s because for each key and salt I like to do: (1 key from api +random keyboard input+1 key from api).</p>
<pre>
/**#@+
 * Authentication Unique Keys.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies.
 * This will force all users to have to log in again.
 *
 * @since 2.6.0
 *
 * Get salt to add to hashes to help prevent attacks.
 *
 * The secret key is located in two places: the database in case the secret key
 * isn&#039;t defined in the second place, which is in the wp-config.php file. If you
 * are going to set the secret key, then you must do so in the wp-config.php
 * file.
 *
 * The secret key in the database is randomly generated and will be appended to
 * the secret key that is in wp-config.php file in some instances. It is
 * important to have the secret key defined or changed in wp-config.php.
 *
 * If you have installed WordPress 2.5 or later, then you will have the
 * SECRET_KEY defined in the wp-config.php already. You will want to change the
 * value in it because hackers will know what it is. If you have upgraded to
 * WordPress 2.5 or later version from a version before WordPress 2.5, then you
 * should add the constant to your wp-config.php file.
 *
 * Below is an example of how the SECRET_KEY constant is defined with a value.
 * You must not copy the below example and paste into your wp-config.php. If you
 * need an example, then you can have a
 * {@link https://api.wordpress.org/secret-key/1.1/ secret key created} for you.
 *
 * Salting passwords helps against tools which has stored hashed values of
 * common dictionary strings. The added values makes it harder to crack if given
 * salt string is not weak.
 *
 * @since 2.5
 * @link https://api.wordpress.org/secret-key/1.1/ Create a Secret Key for wp-config.php
 *
 * @return string Salt value from either &#039;SECRET_KEY&#039; or &#039;secret&#039; option
 */
define(&#039;AUTH_KEY&#039;,        &#039;jflkhaskljdfhkljasdhflkjashd;flkjhas;djfh;kajshdflkjashdlfkjhasdlkfhal?p[B+GR{@&gt;{Yq`c|LnG;dvq#| %OA_cbBSU6,rICC1o/c)-|&#039;);
define(&#039;SECURE_AUTH_KEY&#039;, &#039;jflkhaskljdfhkljasdhflkjashd;flkjhas;djfh;kajshdflkjashdlfkjhasdlkfhal?Vp[Bb15baar8&#038;R-r&lt;[T|?(xhJJABGq+Ux+U$)-Hltp/&#039;);
define(&#039;LOGGED_IN_KEY&#039;,   &#039;jflkhaskljdfhkljasdhflkjashd;flkjhas;djfh;kajshdflkjashdlfkjhasdlkfhal?Vp[B&lt;5n6DG|YWnJ9tY2!M1L)`{-$LW~~Ia%.uCbn!P. 41o2$Z$4&#039;);
define(&#039;NONCE_KEY&#039;,       &#039;jflkhaskljdfhkljasdhflkjashd;flkjhas;djfh;kajshdflkjashdlfkjhasdlkfhal?Vp[Bgu&lt;wM*zewR0.{+m:bmrB?wj!B,4]Wo+4 Avk ApR-D?E&#039;);
define(&#039;SECRET_KEY&#039;,     &#039;jflkhaskljdfhkljasdhflkjashd;flkjhas;djfh;kajshdflkjashdlfkjhasdlkfhal?Vp[B52ugH6muE9r4._iZwoYKUybrqLPpv|d Xr+|yrqhUE&#039;);
&nbsp;
define(&#039;AUTH_SALT&#039;,        &#039;123423190847olqkfhladhfsldshafasdfasdf09a7f-90a87df98adfyapoiyaf9asd8f70a9s8d7f908a7sdf97W4qCdm~Ky%+%~PPa5b YEmDI%U[W!-B&#039;);
define(&#039;SECURE_AUTH_SALT&#039;, &#039;123423190847olqkfhladhfsldshafasdfasdf09a7f-90a87df98adfyapoiyaf9asd8f70a9s8d7f908a7sdf97W4qCdmad/7o6.AU3%9o-|Kqm]+eUqr-n~:ag&#039;);
define(&#039;LOGGED_IN_SALT&#039;,   &#039;123423190847olqkfhladhfsldshafasdfasdf09a7f-90a87df98adfyapoiyaf9asd8f70a9s8d7f908a7sdf97W4qCdmsLiCv@KJ{#wd(?qe(KcH3!&#039;);
define(&#039;NONCE_SALT&#039;,       &#039;123423190847olqkfhladhfsldshafasdfasdf09a7f-90a87df98adfyapoiyaf9asd8f70a9s8d7f908a7sdf97W4qCdmG9&gt;+wm 2)bS0Pd_+1rx0brX]ND8|&#039;);
define(&#039;SECRET_SALT&#039;,      &#039;123423190847olqkfhladhfsldshafasdfasdf09a7f-90a87df98adfyapoiyaf9asd8f70a9s8d7f908a7sdf97W4qCdm2&lt;&gt;))U|sty)+4vpWooKls/^[vN&#039;);
/**#@-*/
</pre>
<hr class="C" />
<h2>Using SSL for Admin and Login</h2>
<p>SSL is kinda required from my point of view, it is just way to easy to sniff data off the wire otherwise.  At least with SSL you force them to use tools like burpsuite, paros proxy, webscarab, etc..</p>
<pre>
/** @since 2.6.0  */
!defined(&#039;FORCE_SSL_ADMIN&#039;) &#038;&#038; define(&#039;FORCE_SSL_ADMIN&#039;, true);
&nbsp;
/** @since 2.6.0  */
!defined(&#039;FORCE_SSL_LOGIN&#039;) &#038;&#038; define(&#039;FORCE_SSL_LOGIN&#039;, true);
</pre>
<h3>Mod_Rewrite to Force SSL</h3>
<p>This is pretty cool, it forces non-https for all urls except for /wp-admin and wp-login.php, which both require https.  It also checks for the logged_in_cookie, and if that is present in the request then it doesn't force non-https.  Kinda confusing if you don't have a <a href="http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html">mod_rewrite cheatsheet</a>.</p>
<pre>
RewriteCond %{THE_REQUEST} ^$ [OR]
RewriteCond %{REQUEST_URI} ^/(wp-admin|wp-login\.php).*$ [NC,OR]
RewriteCond %{HTTP_COOKIE} ^.*wp_li_sadfsdfasdf11b361cdsdfasdfasd=.*$ [NC]
RewriteRule .* - [S=1]
&nbsp;
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{HTTP_HOST} !^www\.askapache\.com$ [NC]
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
&nbsp;
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(wp-admin/.*|wp-login\.php.*)\ HTTP/ [NC]
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</pre>
<hr class="C" />
<h2>File System Permissions</h2>
<p><a class="IFR" href="http://www.askapache.com/security/chmod-umask-fileperms-stat-tricks.html"><img src="/wp-content/uploads/2008/11/danger-chmod-screenshot.png" alt="chmod, umask, file permissions test" title="chmod, umask, file permissions test" /></a>You can get a basic and solid intro on file permissions by reading: <a href="http://codex.wordpress.org/Changing_File_Permissions">Changing File Permissions</a>, or you can check out some of my <a href="http://www.askapache.com/security/chmod-umask-fileperms-stat-tricks.html">file permission research</a>.<br class="C" /></p>
<pre>
/** The permissions as octal number, usually 0644 for files, 0755 for dirs.
 *  http://codex.wordpress.org/Changing_File_Permissions
 *  if ( !$wp_filesystem-&gt;mkdir($remote_destination, FS_CHMOD_DIR) )
 */
!defined(&#039;FS_CHMOD_DIR&#039;) &#038;&#038; define(&#039;FS_CHMOD_DIR&#039;, (0755 &#038; ~ umask()));
!defined(&#039;FS_CHMOD_FILE&#039;) &#038;&#038; define(&#039;FS_CHMOD_FILE&#039;, (0644 &#038; ~ umask()));
/**#@-*/
&nbsp;
/** Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default. */
//stream_set_timeout( $stream, FS_TIMEOUT );
//!defined(&#039;FS_TIMEOUT&#039;) &#038;&#038; define(&#039;FS_TIMEOUT&#039;, 30);
&nbsp;
//$this-&gt;link = @ftp_connect($this-&gt;options[&#039;hostname&#039;], $this-&gt;options[&#039;port&#039;], FS_CONNECT_TIMEOUT);
//!defined(&#039;FS_CONNECT_TIMEOUT&#039;) &#038;&#038; define(&#039;FS_CONNECT_TIMEOUT&#039;, 30);
&nbsp;
// function get_filesystem_method($args = array(), $context = false) {
//  $method = defined(&#039;FS_METHOD&#039;) ? FS_METHOD : false; //Please ensure that this is either &#039;direct&#039;, &#039;ssh&#039;, &#039;ftpext&#039; or &#039;ftpsockets&#039;
//!defined(&#039;FS_METHOD&#039;) &#038;&#038; define(&#039;FS_METHOD&#039;, &#039;direct&#039;);
&nbsp;
/** These methods for the WordPress core, plugin, and theme upgrades try to determine the WordPress path, as reported by PHP, but symlink trickery can sometimes
 * &#039;muck this up&#039; so if you know the paths to the various folders on the server, as seen via your FTP user, you can manually define them in the wp-config.php file.
 * FS_METHOD forces the filesystem method. It should only be "direct", "ssh", "ftpext", or "ftpsockets".
 * FTP_BASE is the full path to the "base" folder of the WordPress installation.
 * FTP_CONTENT_DIR is the full path to the wp-content folder of the WordPress installation.
 * FTP_PLUGIN_DIR is the full path to the plugins folder of the WordPress installation.
 * FTP_PUBKEY is the full path to your SSH public key.
 * FTP_PRIKEY is the full path to your SSH private key.
 * FTP_USER is either user FTP or SSH username. Most likely these are the same, but use the appropriate one for the type of update you wish to do.
 * FTP_PASS is the password for the username entered for FTP_USER. If you are using SSH public key authentication this can be omitted.
 * FTP_HOST is the hostname:port combination for your SSH/FTP server. The standard FTP port is 21 and the standard SSH port is 22.
 */
//define(&#039;FS_METHOD&#039;, &#039;ftpext&#039;);
//define(&#039;FTP_BASE&#039;, &#039;/path/to/wordpress/&#039;);
//define(&#039;FTP_CONTENT_DIR&#039;, &#039;/path/to/wordpress/wp-content/&#039;);
//define(&#039;FTP_PLUGIN_DIR &#039;, &#039;/path/to/wordpress/wp-content/plugins/&#039;);
//define(&#039;FTP_PUBKEY&#039;, &#039;/home/username/.ssh/id_rsa.pub&#039;);
//define(&#039;FTP_PRIKEY&#039;, &#039;/home/username/.ssh/id_rsa&#039;);
//define(&#039;FTP_USER&#039;, &#039;username&#039;);
//define(&#039;FTP_PASS&#039;, &#039;password&#039;);
//define(&#039;FTP_HOST&#039;, &#039;ftp.example.org:21&#039;);
&nbsp;
/**
 * Block requests through the proxy.
 *
 * Those who are behind a proxy and want to prevent access to certain hosts may do so. This will
 * prevent plugins from working and core functionality, if you don&#039;t include api.wordpress.org.
 *
 * You block external URL requests by defining WP_HTTP_BLOCK_EXTERNAL in your wp-config.php file
 * and this will only allow localhost and your blog to make requests.
 * The constant WP_ACCESSIBLE_HOSTS will allow additional hosts to go through for requests. The format of the
 * WP_ACCESSIBLE_HOSTS constant is a comma separated list of hostnames to allow.
 *
 * @since 2.8.0
 * @link http://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
/** @since 2.9  */
//!defined(&#039;WP_HTTP_BLOCK_EXTERNAL&#039;) &#038;&#038; define( &#039;WP_HTTP_BLOCK_EXTERNAL&#039;, false );
&nbsp;
/*
 * The constant WP_ACCESSIBLE_HOSTS will allow additional hosts to go through for requests. The format of the
 * WP_ACCESSIBLE_HOSTS constant is a comma separated list of hostnames to allow.
 *
 * @since 2.8.0
 * @link http://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
 * $accessible_hosts = preg_split(&#039;|,\s*|&#039;, WP_ACCESSIBLE_HOSTS);
 * return !in_array( $check[&#039;host&#039;], $accessible_hosts ); //Inverse logic, If its in the array, then we can&#039;t access it.
 */
//!defined(&#039;WP_ACCESSIBLE_HOSTS&#039;) &#038;&#038; define( &#039;WP_ACCESSIBLE_HOSTS&#039;, &#039;askapache.com,askapache.org&#039; );
</pre>
<hr class="C" />
<h3>Cookies!</h3>
<p>There&#8217;s always a little comfort in having non-default cookies for security (against auto-bots), and using shorter names also means smaller HTTP Packets.</p>
<p>The <code>$cookie_hash</code> is my hack to get around the fact that <code>COOKIEHASH</code> isn&#8217;t definable in <code>wp-config</code>.</p>
<pre>
/**#@+
 * COOKIES
 * Used to guarantee unique hash cookies @since 1.5 */
$cookie_hash=md5(WP_SITEURL);
&nbsp;
/** Set a cookie now to see if they are supported by the browser.
 * setcookie(TEST_COOKIE, &#039;WP Cookie check&#039;, 0, COOKIEPATH, COOKIE_DOMAIN);
 * @since 2.3.0 */
!defined(&#039;TEST_COOKIE&#039;) &#038;&#038; define(&#039;TEST_COOKIE&#039;, &#039;wp_tc&#039;);
&nbsp;
/* @since 2.6.0 */
!defined(&#039;LOGGED_IN_COOKIE&#039;) &#038;&#038; define(&#039;LOGGED_IN_COOKIE&#039;, &#039;wp_li_&#039; . $cookie_hash);
&nbsp;
/* @since 2.6.0 */
!defined(&#039;SECURE_AUTH_COOKIE&#039;) &#038;&#038; define(&#039;SECURE_AUTH_COOKIE&#039;, &#039;wp_sa_&#039; . $cookie_hash);
&nbsp;
/* @since 2.5.0 */
!defined(&#039;AUTH_COOKIE&#039;) &#038;&#038; define(&#039;AUTH_COOKIE&#039;, &#039;wp_a_&#039; . $cookie_hash);
&nbsp;
/* @since 2.0.0 */
!defined(&#039;PASS_COOKIE&#039;) &#038;&#038; define(&#039;PASS_COOKIE&#039;, &#039;wp_p_&#039; . $cookie_hash);
&nbsp;
/* @since 2.0.0 */
!defined(&#039;USER_COOKIE&#039;) &#038;&#038; define(&#039;USER_COOKIE&#039;, &#039;wp_u_&#039; . $cookie_hash);
&nbsp;
/* ok unset this var, its not needed as COOKIEHASH will have this value, but is not definable in wp-config.php */
unset($cookie_hash);
&nbsp;
/** @since 1.2.0 */
!defined(&#039;COOKIEPATH&#039;) &#038;&#038; define(&#039;COOKIEPATH&#039;, preg_replace(&#039;|https?://[^/]+|i&#039;, &#039;&#039;, WP_HOME . &#039;/&#039; ) );
&nbsp;
/** @since 1.5.0 */
!defined(&#039;SITECOOKIEPATH&#039;) &#038;&#038; define(&#039;SITECOOKIEPATH&#039;, preg_replace(&#039;|https?://[^/]+|i&#039;, &#039;&#039;, WP_SITEURL . &#039;/&#039; ) );
&nbsp;
/** @since 2.6.0 */
!defined(&#039;ADMIN_COOKIE_PATH&#039;) &#038;&#038; define( &#039;ADMIN_COOKIE_PATH&#039;, SITECOOKIEPATH . &#039;wp-admin&#039; );
&nbsp;
/** @since 2.6.0 */
!defined(&#039;PLUGINS_COOKIE_PATH&#039;) &#038;&#038; define( &#039;PLUGINS_COOKIE_PATH&#039;, preg_replace(&#039;|https?://[^/]+|i&#039;, &#039;&#039;, WP_PLUGIN_URL)  );
&nbsp;
/** @since 2.0.0 */
!defined(&#039;COOKIE_DOMAIN&#039;) &#038;&#038; define(&#039;COOKIE_DOMAIN&#039;, $_SERVER[&#039;SERVER_NAME&#039;]);
</pre>
<hr class="C" />
<pre>
/**
  * The WP_CACHE setting, if true, includes the wp-content/advanced-cache.php script, when executing wp-settings.php.
  * For an advanced caching plugin to use, static because you would only want one
  * if ( defined(&#039;WP_CACHE&#039;) )@include WP_CONTENT_DIR . &#039;/advanced-cache.php&#039;;
  */
!defined(&#039;WP_CACHE&#039;) &#038;&#038; define(&#039;WP_CACHE&#039;, true);
&nbsp;
/** WordPress Localized Language, defaults to en_US.
 *
 * Change this to localize WordPress.  A corresponding MO file for the chosen
 * language must be installed to wp-content/languages. For example, install
 * de.mo to wp-content/languages and set WPLANG to &#039;de&#039; to enable German
 * language support. */
!defined(&#039;WPLANG&#039;) &#038;&#038; define (&#039;WPLANG&#039;, &#039;en_US&#039;);
&nbsp;
/** Stores the location of the language directory. First looks for language folder in WP_CONTENT_DIR
 *   and uses that folder if it exists. Or it uses the "languages" folder in WPINC. @since 2.1.0 */
//!defined(&#039;WP_LANG_DIR&#039;) &#038;&#038; define(&#039;WP_LANG_DIR&#039;, ABSPATH . WPINC . &#039;/languages&#039;);
&nbsp;
/** LANGDIR defines what directory the WPLANG .mo file resides. If LANGDIR is not defined WordPress looks first to wp-content/languages and then wp-includes/languages for the .mo defined by WPLANG file.  Old static relative path maintained for limited backwards compatibility - won&#039;t work in some cases*/
//!defined(&#039;LANGDIR&#039;) &#038;&#038; define(&#039;LANGDIR&#039;, &#039;wp-content/languages&#039;);
&nbsp;
/** Stores the location of the WordPress directory of functions, classes, and core content. @since 1.0.0 */
//!defined(&#039;WPINC&#039;) &#038;&#038; define(&#039;WPINC&#039;, &#039;wp-includes&#039;);
</pre>
<hr class="C" />
<h2>WPMU Stuff</h2>
<p>I personally don&#8217;t use.</p>
<pre>
/** Allows for the mu-plugins directory to be moved from the default location. @since 2.8.0 */
//!defined(&#039;WPMU_PLUGIN_DIR&#039;) &#038;&#038; define( &#039;WPMU_PLUGIN_DIR&#039;, WP_CONTENT_DIR . &#039;/mu-plugins&#039; ); // full path, no trailing slash
&nbsp;
/** Allows for the mu-plugins directory to be moved from the default location. @since 2.8.0 */
//!defined(&#039;WPMU_PLUGIN_URL&#039;) &#038;&#038; define( &#039;WPMU_PLUGIN_URL&#039;, WP_CONTENT_URL . &#039;/mu-plugins&#039; ); // full url, no trailing slash
&nbsp;
/** Allows for the mu-plugins directory to be moved from the default location. @since 2.8.0 */
//!defined( &#039;MUPLUGINDIR&#039; ) &#038;&#038; define( &#039;MUPLUGINDIR&#039;, &#039;wp-content/mu-plugins&#039; ); // Relative to ABSPATH.  For back compat.
</pre>
<hr class="C" />
<h2>WordPress Database</h2>
<p>This is usually the only thing I have to manually edit when creating a new site, unless I just use the same DB and modify the $table_prefix, (farther down). I run everything I possibly can in UTF-8, but if you don&#8217;t already know alot about character sets, wow it is one of the most confusing things so you may want to save learning about that topic for another day.  Otherwise the following are helpful (<em>and show how confusing character sets are!</em>)</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html">Character Sets and Collations MySQL Support</a></li>
<li><a href="http://codex.wordpress.org/Converting_Database_Character_Sets">Converting Database Character Sets</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html">UTF-8 character sets</a> (<a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>)</li>
</ul>
<p>If you ever setup WP to use the builtin membership features, make sure you learn about the <code>CUSTOM_USER_TABLE</code> and <code>CUSTOM_USER_META_TABLE</code> constants, I&#8217;ve found them very helpful.</p>
<pre>
/**#@+
 * MySQL settings
 */
/** The name of the database for WordPress */
define(&#039;DB_NAME&#039;, &#039;askapachewpblog75&#039;);
&nbsp;
/** The username to access the database */
define(&#039;DB_USER&#039;, &#039;askapache245d&#039;);
&nbsp;
/** The password for the username to access the database */
define(&#039;DB_PASSWORD&#039;, &#039;asdfklj2340&#039;);
&nbsp;
/** The hostname to connect to the database at */
define(&#039;DB_HOST&#039;, &#039;mysql.askapache.com&#039;);
&nbsp;
/** The charset of the database */
define(&#039;DB_CHARSET&#039;, &#039;utf8&#039;);
&nbsp;
/** The collation of the database */
define(&#039;DB_COLLATE&#039;, &#039;utf8_general_ci&#039;);
</pre>
<hr class="C" />
<h2>$table_prefix</h2>
<p>The <code>$table_prefix</code> is the value placed in the front of your database tables. Change the value if you want to use something other than wp_ for your database prefix. Typically this is changed if you are <a href="http://codex.wordpress.org/Installing_Multiple_Blogs">installing multiple WordPress blogs</a> in the same database, and also for enhanced security.</p>
<p>Its a safe and good idea to change this value pre-installation to add more security to your WordPress blog. Exploits attempted against your WordPress blog by malicious crackers often are built with the premise that your blog uses the prefix wp_, by changing the value you mitigate some attack vectors. </p>
<pre>
/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each a unique
 * prefix. Only numbers, letters, and underscores please!
 */
$table_prefix  = &#039;ar15_&#039;;
&nbsp;
/** CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE are used to designated that the user and usermeta tables normally utilized by WordPress are not used, instead these values/tables are used to store your user information. */
//!defined(&#039;CUSTOM_USER_TABLE&#039;) &#038;&#038; define(&#039;CUSTOM_USER_TABLE&#039;, $table_prefix . &#039;my_users&#039;);
//!defined(&#039;CUSTOM_USER_META_TABLE&#039;) &#038;&#038; define(&#039;CUSTOM_USER_META_TABLE&#039;, $table_prefix . &#039;my_usermeta&#039;);
</pre>
<h2>Setup PHP Ini Settings</h2>
<pre>
&nbsp;
/** Turns the output of errors on or off, you really never want this on, you should only view errors by reading the log file. */
ini_set(&#039;display_errors&#039;, WP_DEBUG_DISPLAY);
&nbsp;
/** Tells whether script error messages should be logged to the server&#039;s error log or error_log. */
ini_set(&#039;log_errors&#039;, &#039;On&#039;);
&nbsp;
/** http://us.php.net/manual/en/timezones.php */
ini_set(&#039;date.timezone&#039;, &#039;America/Indianapolis&#039;);
&nbsp;
/** Where to log php errors */
ini_set(&#039;error_log&#039;, ASKAPACHE_ROOT . &#039;/logs/php_error.log&#039;);
&nbsp;
/** Set the memory limit, otherwise defaults to &#039;32M&#039; */
ini_set(&#039;memory_limit&#039;, WP_MEMORY_LIMIT);
</pre>
<h2>Sessions are slow</h2>
<p>So I only use sessions when I have a specific use&#8230; In this case I need sessions only when one of the tools in the /online-tools/ directory is being used.  And that is for the <a href="http://www.askapache.com/security/php-captcha-anti-spam-example.html">captcha image</a>.  In the future I won&#8217;t ever use sessions.</p>
<pre>
if(preg_match( &#039;#^/online-tools/#&#039;,$_SERVER[&#039;REQUEST_URI&#039;])) session_start();
</pre>
<h2>Include Custom Files</h2>
<p>Sure you could use the my-hacks.php that WP allows, or you can just stick your functions in your <code>TEMPLATEPATH/functions.php</code> file, but they are executed only after the wp-settings.php file, which may be too late for your file.</p>
<p>In the past I&#8217;ve also used the <a href="http://us2.php.net/manual/en/ini.core.php#ini.auto-prepend-file">auto_prepend_file</a> settings to run my script before anything (index.php) but I ran into some issues on different hosts, and it wasn&#8217;t as portable.</p>
<p>This is useful because you can have a file with globally available functions that you can use in non-WP areas as well as WP areas.  I am moving away from this more and more as I learn more about classes and build plugins instead for portability.</p>
<pre>
include_once ASKAPACHE_ROOT . &#039;/includes/myfunctions.inc&#039;;
&nbsp;
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . &#039;wp-settings.php&#039;);
?&gt;
</pre>
<h2>Some Useful PHP</h2>
<p>I am constantly trying to make my sites and code more portable, so I am using plugins alot more to accomplish things that I use to do with separate php.  Here are some examples of minimal php.</p>
<pre>
add_filter("the_generator", create_function(&#039;$a&#039;,&#039;return "";&#039;));
add_filter(&#039;the_content&#039;, create_function(&#039;$a&#039;, &#039;return ((is_feed())? $a."&lt;p&gt;&lt;a href=\"".get_permalink()."\"&gt;".get_the_title()."&lt;/a&gt; originally appeared on ".get_bloginfo("name").".&lt;/p&gt;" : $a);&#039;), 99999);
add_filter(&#039;excerpt_length&#039;, create_function(&#039;$a&#039;, &#039;return 300;&#039;),99);
add_filter(&#039;excerpt_more&#039;, create_function(&#039;$a&#039;, &#039;return "&hellip;";&#039;),99);
add_action( &#039;wp_head&#039;, create_function(&#039;$a&#039;,&#039;echo "&lt;link rel=\"pingback\" href=\"&#039;.get_bloginfo(&#039;pingback_url&#039;).&#039;\" /&gt;\n";&#039;), 95 );
add_action( &#039;wp_head&#039;, create_function(&#039;$a&#039;,&#039;echo "&lt;link rel=\"schema.rss\" href=\"http://purl.org/rss/1.0/\" /&gt;\n";&#039;), 96 );
add_action( &#039;wp_head&#039;, create_function(&#039;$a&#039;,&#039;echo "&lt;link rel=\"schema.rel\" href=\"http://purl.org/vocab/relationship/\" /&gt;\n";&#039;), 97 );
add_action( &#039;wp_head&#039;, create_function(&#039;$a&#039;,&#039;echo "&lt;link rel=\"meta\" type=\"application/rdf+xml\" href=\"/foaf.rdf\" /&gt;\n";&#039;), 98 );
add_action( &#039;wp_head&#039;, create_function(&#039;$a&#039;,&#039;echo "&lt;link href=\"/favicon.ico\" rel=\"shortcut icon\" type=\"image/x-icon\" /&gt;\n";&#039;), 99 );
</pre>
<h2>Debugging Note</h2>
<p><a href="http://wordpress.org/extend/plugins/askapache-debug-viewer/screenshots/"><img alt="AskApache Advanced Debugging Output" src="http://s.wordpress.org/extend/plugins/askapache-debug-viewer/screenshot-1.png?r=160129" title="AskApache Advanced Debugging Output" width="625" height="548" /></a>If you read this far than you probably know how important debugging is, but I sometimes like to stick the best tips deep in my articles to make sure only YOU find it.  GRTFM isn&#8217;t used on this site, it&#8217;s mostly a requirement because my writing can get pretty bad..  The point, debugging is more than a crucial requirement if you want to do anything cool.  Don&#8217;t worry I got you.. check my <a href="http://wordpress.org/extend/plugins/askapache-debug-viewer/">AskApache Debug Viewer Plugin from the official WP site</a>.  It&#8217;s pretty close to providing as verbose amount of information that I could possibly figure out how to get out of php, probably more than you have ever seen at least, I focused on quantity.  I use it all the time on new installs as there is no setup required and it tells me advanced information about the setup of the server, hacker code for sure.<br class="C" /></p>
<p>Here&#8217;s a quick function to see set global vars, I just think this is interesting code.</p>
<pre>
function askapache_global_debug(){
  global $_GET,$_POST,$_COOKIE,$_SESSION,$_ENV,$_FILES,$_SERVER,$_REQUEST,$HTTP_POST_FILES,$HTTP_POST_VARS,$HTTP_SERVER_VARS,$HTTP_RAW_POST_DATA,$HTTP_GET_VARS,$HTTP_COOKIE_VARS,$HTTP_ENV_VARS;
  $gv=create_function(&#039;$n&#039;,&#039;global $$n; ob_start(); if ( is_array($$n) &#038;&#038; sizeof($$n)&gt;0 &#038;&#038; print("[{$n}]\n") ) print_r($$n);return ob_get_clean();&#039;);
  foreach (array(&#039;_GET&#039;,&#039;_POST&#039;,&#039;_COOKIE&#039;,&#039;_SESSION&#039;,&#039;_ENV&#039;,&#039;_FILES&#039;,&#039;_SERVER&#039;,&#039;_REQUEST&#039;,&#039;HTTP_POST_FILES&#039;,&#039;HTTP_POST_VARS&#039;,&#039;HTTP_SERVER_VARS&#039;,&#039;HTTP_RAW_POST_DATA&#039;,&#039;HTTP_GET_VARS&#039;,&#039;HTTP_COOKIE_VARS&#039;,&#039;HTTP_ENV_VARS&#039;) as $k)echo $gv($k);
  print_r(get_defined_constants());
}
</pre>
<p class="anote">Also check the WordPress Codex page: <a href="http://codex.wordpress.org/Editing_wp-config.php">Editing wp-config.php</a></p>
<p><a href="http://www.askapache.com/wordpress/advanced-wp-config-php-tweaks.html">Advanced WordPress wp-config.php Tweaks</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/advanced-wp-config-php-tweaks.html/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>An AskApache Plugin Upgrade to Rule them All</title>
		<link>http://www.askapache.com/wordpress/an-askapache-plugin-upgrade-to-rule-them-all.html</link>
		<comments>http://www.askapache.com/wordpress/an-askapache-plugin-upgrade-to-rule-them-all.html#comments</comments>
		<pubDate>Wed, 29 Jul 2009 17:59:07 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Apache Modules]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Linux Unix BSD]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[Web Tools]]></category>
		<category><![CDATA[Webmaster]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[AskApache Google 404]]></category>
		<category><![CDATA[AskApache Password Protection]]></category>
		<category><![CDATA[Fsockopen]]></category>
		<category><![CDATA[wordpress security]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=3062</guid>
		<description><![CDATA[<p><a class="IFL" href="/wp-content/uploads/2009/07/apache-server-status.png"><img src="/wp-content/uploads/2009/07/apache-server-status-350x164.png" alt="apache-server-status" title="apache-server-status" width="350" height="164" class="alignnone size-medium wp-image-3070" /></a>So my blog as been rather quiet for almost a year now, and very few updates if any have been released for my Password Protection PLugin, my Google 404 Plugin, and definately not for my AskApache CrazyCache plugin, which I will be releasing last...  So for all of you who've helped me out by sending me suggestions and notifying me of errors and sticking with it...  Just wanted to <strong>say sorry about that, and thanks for all the great ideas.. </strong> Well, I've been sticking with it as well believe it our not.  I manage to get free days once in a while, and then its <strong>time to jam</strong>.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a class="IFL" href="/wp-content/uploads/2009/07/apache-server-status.png"><img src="/wp-content/uploads/2009/07/apache-server-status-350x164.png" alt="apache-server-status" title="apache-server-status" width="350" height="164" class="alignnone size-medium wp-image-3070" /></a>So my blog as been rather quiet for almost a year now, and very few updates if any have been released for my Password Protection PLugin, my Google 404 Plugin, and definately not for my AskApache CrazyCache plugin, which I will be releasing last&#8230;  So for all of you who&#8217;ve helped me out by sending me suggestions and notifying me of errors and sticking with it&#8230;  Just wanted to <strong>say sorry about that, and thanks for all the great ideas.. </strong> Well, I&#8217;ve been sticking with it as well believe it our not.  I manage to get free days once in a while, and then its <strong>time to jam</strong>.</p>
<p>I&#8217;ve used just about every CMS/Blog/Forum/Trac/Gallery/etc) and really didn&#8217;t like a lot of the way they coded&#8230;  I could use php but I didn&#8217;t KNOW php.. so I&#8217;ve had to learn php also, and it was tough to learn the advanced class usage and all the other language specific (but similar) constructs for php.  It was especially difficult (but fun and challenging) to program so as to be compatible with php4 and php5 (Such is WordPress).    But I kept at it, and soon you can decide for yourself what to make of it.</p>
<p>I can code in plenty of languages (bash, lua, windows .bat and vbs,  ocaml, big fan of all things shell) and can work my way through C and even sorta somewhat with assembly.  Assembly is the hardest, by far,  I&#8217;m into easy and powerful languages like Python, Javascript, perl, php, ruby, and CGI. I&#8217;ve used PHP for a long time to do various things,  but never to build software projects like this.  Once I noticed WordPress&#8217;s core .php files and the excellent programming I wanted to try and learn hot to do it.   The WordPress code is some of the best I&#8217;ve seen.  It appears the way they built it was planned, and not just dreamt up while typing that I can&#8217;t help but do.    Every time I read through the core code I learn a new trick or very nice way to do something.  Those guys are really good, and I think WordPress is going to dominate for a long long time.</p>
<h2>The Strategy</h2>
<p>The Password Protection (passpro) plugin has a lot of complex stuff going on, especially for a newbie to PHP and WordPress like me, so after refactoring the whole thing at least 5 times I decided to modify my approach, and wrote the AskApache Google 404 Plugin as a way to practice on a simpler piece of code, while at the same time providing a plugin of value.   Eventually I stopped thinking I could just code the whole thing in one sit-down with a stream-of-consciousness, and had to instead modularize the code and focus in on each part before moving to the next (I go without a plan because its fun, just not the most productive, but again, I&#8217;m not a programmer in the scientific sense.).</p>
<p>So I decided I had to really learn how WordPress Plugins work, filters, hooks, actions, and basically comfortability at reverse-engineering code, (Im a beginner for the last time), and so with the upcoming release of the AskApache Google 404 Plugin I have succeeded in making an incredibly stable plugin.  That way I only have to worry about what the aapasspro plugin is doing, instead of trying to fit it into a framework.  </p>
<h2>AskApache Google 404 Upgrade</h2>
<p>I think its rather unusual to develop a nice plugin like this 404 handler merely for the purpose of improving upon another plugin, but hey it worked.  As of <em>08/03/2009 14:06PM EST</em> I have about 1 hour left of finishing touches to release this upgrade.  But as you cantell by my badly edited posts, I don&#8217;t have a lot of time to myself.  An hour here and there is about it.  So it could be up to 2 weeks before I actually have the time to commit the release to the repo.  On a sidenote, have you checked out <a href="http://windows7news.com/" title="Windows 7 News">Windows 7 News</a>?  I&#8217;ve been contracted to do some technical work for them and thought they had an excellent site.</p>
<p><a href="/wp-content/uploads/2009/07/askapache-google-upgrade-ss1.png"><img src="/wp-content/uploads/2009/07/askapache-google-upgrade-ss1-344x350.png" alt="askapache-google-upgrade-ss1" title="askapache-google-upgrade-ss1" width="344" height="350" class="alignnone size-medium wp-image-3139" /></a></p>
<p><a href="/wp-content/uploads/2009/07/askapache-google-upgrade-ss2.png"><img src="/wp-content/uploads/2009/07/askapache-google-upgrade-ss2-293x350.png" alt="askapache-google-upgrade-ss2" title="askapache-google-upgrade-ss2" width="293" height="350" class="alignnone size-medium wp-image-3138" /></a></p>
<p>But keep in mind, the 404 PLugin is just where I practice for the passpro plugin, which truly does have features that no other software like it has ever had.  I understand the technology behind this plugin, and know it would really have a great impact on improving the Web (esp. WordPress) for all of us, I&#8217;ve just had to learn how to make it.</p>
<h2>AskApache Password Protection</h2>
<p>Probably still a couple weeks away, this plugin is the ultimate culmination of apache hackers dreams, at least those on shared servers (who may be interested in learning how to bypass security of said servers)..  So this is something I have much too fun with doing what I like to do.. network/protocol-level security.  I&#8217;ve examined the source code for many software packages that I use or have used to audit a server&#8217;s security, and this simple php plugin in most instances can enumerate with accuraccy most of the server&#8217;s setup in about a minute.  The catch (and the file permission problems I had to find a workaround too) is that this software is launched on the server, not remotely against the server.</p>
<p>Some of the software I examined was whiskers, nessus, nmap, hping, mozilla source, wireshark, ncftp, netcat, etc..  The closest comparison to the socket-level class I&#8217;ve hacked together to those is wireshark.  Except that wireshark only interprets (captures) the data passing over the wire, while this class does that and in fact sends and receives the data like netcat or nmap.  Its really more similar to metasploit, and can easily be used to send hex, binary, ascii, or any type of payload to the remote or local host.</p>
<h2>The Upgrades Begin</h2>
<p>Well I started working on them a long time ago.  Both the Password Protection plugin and the Google 404 plugin needed serious work.   And I finally have it all figured out.  Essentially I would work on one and finish an upgrade, but I just wasn&#8217;t happy with it and I wold start all over again, refactoring the code.   So as I put the finishing touches on those 2 plugins keep an eye out.  They are major upgrades.   I was able to meet all the goals I had for them, and came up with a lot of more improvements during the process.One of the main things I needed was a socket-level class to perform all kinds of checks and tests on.  I need this also for my crazy cache plugin, which my blog is currently using ,  and I have a 2 more really nice pplugins I use that also needed  access to a network class.  I wrote about what I was doing with fsockopen, and I&#8217;ve been improving on that example ever since.  I use this class to do some really powerful and exciting stuff, but you&#8217;ll see it soon enough.  As an indication of &#8216;getting it right&#8217; for the Password Protection plugin, the plugin will now work on Windows, Apache, IIS, Lighthttpd, and will even work running on a blackberry web server.  So now everyone using wordpress can at least get some security()</p>
<p class="enote">Many of the the other improvements focus on using the fsockopen class and .htaccess tricks to basically enumerate and discover all the different capabilities of your particular server;  That way you can learn about all the features and security that are possible for your specific server, and the securty modules wi8ll be geared for that as well.  FINALLY this plugin is going to be stable, and I just cant wait to see how people react when they learn all great capability their Apache-based Server has that they didn&#8217;t have a clue about.   Its amazing in that sense, and hackers will love theh way it works.. but your server admins will love it even more because its entirely 100% focused on helping you to set your site up (if you have Apache) to keep spammers out, to keep virii-serving robots and their log-hogging exploit requests and CPU/Mem robiing 404 errors off of your servers for real.  This will have a noticeable affect to whoever is running the server.   As you can tell.. I am pumped!</br></p>
<hr class="C" />
Apache is easy to configure and use, but only when you have root access.  Most people on shared and private hosting aren&#8217;t even able to view the main config file, let alone execute the Apache binaries to see what features are available and what configuration is being used.<br class="C" /></p>
<p>Apache can only be influenced by the main server configs and by .htaccess files.  Not by php, not by perl, and the main configs are almost never accessible to the masses.  But .htaccess files are.  And many hosting providers allow and enable .htaccess files, a configuration file for your web server.  The advanced features and capabilities of Apache were out of reach for most of us, it just wasn&#8217;t possible to enumerate or access, and most hosting providers are infamous for their lack of .htaccess (customer) support.  This plugin goes around those problems to give the power back to the people.<br class="C" /></p>
<p>y creating custom .htaccess files containing unpublished .htaccess tricks and techniques and combining that with the use of socket-level networking from WordPress (PHP) using <a href="http://www.askapache.com/php/fsockopen-socket.html">fsockopen</a>, we can effectively enumerate and discover an incredible amount of features and settings you will be able to control and use with this plugin.</p>
<p>Here are a few examples of the capabilities of this plugin, some of which I believe no other software can do..  <em>(Open source free to copy!)</em>.</p>
<ol>
<li>Current Version of Apache (<strong>Down to the API Version</strong>)</li>
<li>List of <strong>ALL Modules currently enabled</strong> by Apache (Such as Mod_Rewrite)</li>
<li>List of <strong>ALL Directives enabled by EACH enabled Module.</strong></li>
<li>Enumerate .htaccess Overrides, Context Permissions</li>
<li>Test for any builtin Handlers (like the <a href="/wp-content/uploads/2009/07/apache-server-status.png">status handler screenshot</a>)</li>
<li>Configure SSI (<a href="http://www.askapache.com/htaccess/advanced-htaccess-ssi.html#htaccess-ssi-security">http://www.askapache.com/htaccess/advanced-htaccess-ssi.html#htaccess-ssi-security</a>)</li>
</ol>
<blockquote cite="http://www.askapache.com/htaccess/password-protection-plugin-status.html"><div class="inote"><cite><a href="http://www.askapache.com/htaccess/password-protection-plugin-status.html"></a></cite>
<p><strong>March 1, 2009</strong><br /><strong>I would focus on the method that WordPress uses</strong>.  The code they have now (2.8 bleeding-edge) still isn&#8217;t where it needs to be, but this is some difficult stuff and <strong>they have a brilliant start, it&#8217;ll work.. just a question of when</strong>.</p>
<p><a class="IFL" href="/wp-content/uploads/2009/03/apache-security-model-tall1.png"><img src="/wp-content/uploads/2009/03/apache-security-model-tall1-250x123.png" alt="Apache Security Model - In Color" title="apache-security-model-wide" width="250" height="123" /></a><strong>The main issue</strong> with the password protection plugin working for some people and not others is due to <a title="detailed file permission article" href="http://www.askapache.com/security/chmod-stat.html">file permission configurations</a>.  The plugin attempts to write/modify files in your blog&#8217;s root directory.<br class="C" /></p>
</div>
</blockquote>
<hr class="C" />
<blockquote cite="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html"><div class="inote"><cite><a href="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html"></a></cite>
<p><strong>November 05, 2008</strong><br />To make a long story short, I downloaded each major release of the apache httpd source code starting at version 1.3.0 and finishing with version 2.2.11, I then compiled each version and built a HTTPD from source for all these apache versions.</p>
<div>
<div style="width:100px;overflow:hidden;float:left;">
<ul>
<li>1.3.0</li>
<li>1.3.1</li>
<li>1.3.11</li>
<li>1.3.12</li>
<li>1.3.14</li>
<li>1.3.17</li>
<li>1.3.19</li>
<li>1.3.2</li>
<li>1.3.20</li>
<li>1.3.22</li>
<li>1.3.23</li>
<li>1.3.24</li>
<li>1.3.27</li>
<li>1.3.28</li>
</ul>
</div>
<div style="width:100px;overflow:hidden;float:left;">
<ul>
<li>1.3.29</li>
<li>1.3.3</li>
<li>1.3.31</li>
<li>1.3.32</li>
<li>1.3.33</li>
<li>1.3.34</li>
<li>1.3.35</li>
<li>1.3.36</li>
<li>1.3.37</li>
<li>1.3.39</li>
<li>1.3.4</li>
<li>1.3.41</li>
<li>1.3.6</li>
<li>1.3.9</li>
</ul>
</div>
<div style="width:100px;overflow:hidden;float:left;">
<ul>
<li>2.0.35</li>
<li>2.0.36</li>
<li>2.0.39</li>
<li>2.0.40</li>
<li>2.0.42</li>
<li>2.0.43</li>
<li>2.0.44</li>
<li>2.0.45</li>
<li>2.0.46</li>
<li>2.0.47</li>
<li>2.0.48</li>
<li>2.0.49</li>
<li>2.0.50</li>
<li>2.0.51</li>
</ul>
</div>
<div style="width:150px;overflow:hidden;float:left;">
<ul>
<li>2.0.52</li>
<li>2.0.53</li>
<li>2.0.54</li>
<li>2.0.55</li>
<li>2.0.58</li>
<li>2.0.59</li>
<li>2.0.61</li>
<li>2.0.63</li>
<li>2.1.3-beta</li>
<li>2.1.6-alpha</li>
<li>2.1.7-beta</li>
<li>2.1.8-beta</li>
<li>2.1.9-beta</li>
</ul>
</div>
<div style="width:100px;overflow:hidden;float:left;">
<ul>
<li>2.2.0</li>
<li>2.2.10</li>
<li>2.2.2</li>
<li>2.2.3</li>
<li>2.2.4</li>
<li>2.2.6</li>
<li>2.2.8</li>
<li>2.2.9</li>
<li><strong>2.2.10</strong></li>
<li><strong>2.2.11</strong></li>
</ul>
</div>
<p><br class="C" /></div>
<p>Then I went through each version and determined the compatible modules for that version, and I&#8217;m pretty confident that I was also able to find each and every directive allowed by the compatible modules for that version (including core directives).  See <a href="http://www.askapache.com/htaccess/htaccess.html#htaccess-directives">.htaccess directive list</a>.  Basically I can now test a server using a variety of methods and determine almost 100% accurately what version of Apache (down to the API) is running, what modules (and versions) are enabled, and each and every directive that is allowed or disallowed for that version.  So this is so awesome because now we can enable all sorts of additional security features.</p>
</div>
</blockquote>
<hr class="C" />
<blockquote cite="http://www.askapache.com/htaccess/htaccess.html#htaccess-modules"><p><cite><a href="http://www.askapache.com/htaccess/htaccess.html#htaccess-modules">Htaccess enabled Modules</a></cite>
<p>Here are most of the modules that come with Apache.  Each one can have new commands that can be used in .htaccess file scopes.</p>
<p><a href="http://www.askapache.com/servers/mod_actions.c.html">mod_actions</a>, <a href="http://www.askapache.com/servers/mod_alias.c.html">mod_alias</a>, <a href="http://www.askapache.com/servers/mod_asis.c.html">mod_asis</a>, <a href="http://www.askapache.com/servers/mod_auth_basic.c.html">mod_auth_basic</a>, <a href="http://www.askapache.com/servers/mod_auth_digest.c.html">mod_auth_digest</a>, <a href="http://www.askapache.com/servers/mod_authn_anon.c.html">mod_authn_anon</a>, <a href="http://www.askapache.com/servers/mod_authn_dbd.c.html">mod_authn_dbd</a>, <a href="http://www.askapache.com/servers/mod_authn_dbm.c.html">mod_authn_dbm</a>, <a href="http://www.askapache.com/servers/mod_authn_default.c.html">mod_authn_default</a>, <a href="http://www.askapache.com/servers/mod_authn_file.c.html">mod_authn_file</a>, <a href="http://www.askapache.com/servers/mod_authz_dbm.c.html">mod_authz_dbm</a>, <a href="http://www.askapache.com/servers/mod_authz_default.c.html">mod_authz_default</a>, <a href="http://www.askapache.com/servers/mod_authz_groupfile.c.html">mod_authz_groupfile</a>, <a href="http://www.askapache.com/servers/mod_authz_host.c.html">mod_authz_host</a>, <a href="http://www.askapache.com/servers/mod_authz_owner.c.html">mod_authz_owner</a>, <a href="http://www.askapache.com/servers/mod_authz_user.c.html">mod_authz_user</a>, <a href="http://www.askapache.com/servers/mod_autoindex.c.html">mod_autoindex</a>, <a href="http://www.askapache.com/servers/mod_cache.c.html">mod_cache</a>, <a href="http://www.askapache.com/servers/mod_cern_meta.c.html">mod_cern_meta</a>, <a href="http://www.askapache.com/servers/mod_cgi.c.html">mod_cgi</a>, <a href="http://www.askapache.com/servers/mod_dav.c.html">mod_dav</a>, <a href="http://www.askapache.com/servers/mod_dav_fs.c.html">mod_dav_fs</a>, <a href="http://www.askapache.com/servers/mod_dbd.c.html">mod_dbd</a>, <a href="http://www.askapache.com/servers/mod_deflate.c.html">mod_deflate</a>, <a href="http://www.askapache.com/servers/mod_dir.c.html">mod_dir</a>, <a href="http://www.askapache.com/servers/mod_disk_cache.c.html">mod_disk_cache</a>, <a href="http://www.askapache.com/servers/mod_dumpio.c.html">mod_dumpio</a>, <a href="http://www.askapache.com/servers/mod_env.c.html">mod_env</a>, <a href="http://www.askapache.com/servers/mod_expires.c.html">mod_expires</a>, <a href="http://www.askapache.com/servers/mod_ext_filter.c.html">mod_ext_filter</a>, <a href="http://www.askapache.com/servers/mod_file_cache.c.html">mod_file_cache</a>, <a href="http://www.askapache.com/servers/mod_filter.c.html">mod_filter</a>, <a href="http://www.askapache.com/servers/mod_headers.c.html">mod_headers</a>, <a href="http://www.askapache.com/servers/mod_ident.c.html">mod_ident</a>, <a href="http://www.askapache.com/servers/mod_imagemap.c.html">mod_imagemap</a>, <a href="http://www.askapache.com/servers/mod_include.c.html">mod_include</a>, <a href="http://www.askapache.com/servers/mod_info.c.html">mod_info</a>, <a href="http://www.askapache.com/servers/mod_log_config.c.html">mod_log_config</a>, <a href="http://www.askapache.com/servers/mod_log_forensic.c.html">mod_log_forensic</a>, <a href="http://www.askapache.com/servers/mod_logio.c.html">mod_logio</a>, <a href="http://www.askapache.com/servers/mod_mem_cache.c.html">mod_mem_cache</a>, <a href="http://www.askapache.com/servers/mod_mime.c.html">mod_mime</a>, <a href="http://www.askapache.com/servers/mod_mime_magic.c.html">mod_mime_magic</a>, <a href="http://www.askapache.com/servers/mod_negotiation.c.html">mod_negotiation</a>, <a href="http://www.askapache.com/servers/mod_proxy.c.html">mod_proxy</a>, <a href="http://www.askapache.com/servers/mod_proxy_ajp.c.html">mod_proxy_ajp</a>, <a href="http://www.askapache.com/servers/mod_proxy_balancer.c.html">mod_proxy_balancer</a>, <a href="http://www.askapache.com/servers/mod_proxy_connect.c.html">mod_proxy_connect</a>, <a href="http://www.askapache.com/servers/mod_proxy_ftp.c.html">mod_proxy_ftp</a>, <a href="http://www.askapache.com/servers/mod_proxy_http.c.html">mod_proxy_http</a>, <a href="http://www.askapache.com/servers/mod_rewrite.c.html">mod_rewrite</a>, <a href="http://www.askapache.com/servers/mod_setenvif.c.html">mod_setenvif</a>, <a href="http://www.askapache.com/servers/mod_speling.c.html">mod_speling</a>, <a href="http://www.askapache.com/servers/mod_ssl.c.html">mod_ssl</a>, <a href="http://www.askapache.com/servers/mod_status.c.html">mod_status</a>, <a href="http://www.askapache.com/servers/mod_substitute.c.html">mod_substitute</a>, <a href="http://www.askapache.com/servers/mod_unique_id.c.html">mod_unique_id</a>, <a href="http://www.askapache.com/servers/mod_userdir.c.html">mod_userdir</a>, <a href="http://www.askapache.com/servers/mod_usertrack.c.html">mod_usertrack</a>, <a href="http://www.askapache.com/servers/mod_version.c.html">mod_version</a>, <a href="http://www.askapache.com/servers/mod_vhost_alias.c.html">mod_vhost_alias</a></p>
</blockquote>
<hr class="C" />
<hr class="C" />
<h2>Debugging HTTP protocol</h2>
<p>Check this out!  I&#8217;m particularly happy about this feature, which outputs an exact trace of any requests made by the plugin (such as during the testing phase) by saving the actual raw data sent out on the wire using fsockopen, RX and TX.  This is useful for a number of reasons, viewing your headers, finding Redirect Loops, testing RewriteRules, and following the request hop-by-hop for debugging.  The below example shows 2 requests for 2 URIs.  The first URI is protected using Digest Authentication, the 2nd shows Basic.</p>
<pre>
 ______________
|  RAW TRACE   |
==================================================================================================================================
GET /htaccess/index.txt?testing=query HTTP/1.1
Host: www.askapache.com
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1) AA_PassPro/1.9 (http://www.askapache.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://www.askapache.com/
&nbsp;
HTTP/1.1 401 Authorization Required
Date: Wed, 22 Jul 2009 06:29:58 GMT
Server: Apache
WWW-Authenticate: Digest realm="do or die", nonce="03328f3ec7c7b", algorithm=MD5, domain="/", qop="auth"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 882
Connection: close
Content-Type: text/html; charset=UTF-8
&nbsp;
GET /htaccess/index.txt?testing=query HTTP/1.1
Host: www.askapache.com
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1) AA_PassPro/1.9 (http://www.askapache.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://www.askapache.com/
Authorization: Digest username="test",realm="do or die",nonce="03328f3ec7c7b",uri="/htaccess/index.txt?testing=query",
cnonce="82d057852a9dc497",nc=00000001,algorithm=MD5,response="9d476e9ea3",qop="auth"
&nbsp;
HTTP/1.1 200 OK
Date: Wed, 22 Jul 2009 06:29:58 GMT
Server: Apache
Authentication-Info: rspauth="9051b01ee26dd62b3e2b40dada694f45", cnonce="82d057852a9dc497", nc=00000001, qop=auth
Last-Modified: Tue, 21 Jul 2009 23:56:00 GMT
Accept-Ranges: bytes
Cache-Control: max-age=3600
Expires: Wed, 22 Jul 2009 07:29:58 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 27
Connection: close
Content-Type: text/plain; charset=UTF-8
&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;``
&nbsp;
 ______________
|  RAW TRACE   |
==================================================================================================================================
GET /htaccess/po.txt?testing=query HTTP/1.1
Host: www.askapache.com
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1) AA_PassPro/1.9 (http://www.askapache.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://www.askapache.com/
&nbsp;
HTTP/1.1 401 Authorization Required
Date: Wed, 22 Jul 2009 06:29:58 GMT
Server: Apache
WWW-Authenticate: Basic realm="Po Pimping"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 878
Connection: close
Content-Type: text/html; charset=UTF-8
&nbsp;
GET /htaccess/po.txt?testing=query HTTP/1.1
Host: www.askapache.com
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1) AA_PassPro/1.9 (http://www.askapache.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://www.askapache.com/
Authorization: Basic adfAGAltcA==
&nbsp;
HTTP/1.1 200 OK
Date: Wed, 22 Jul 2009 06:29:58 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 05:54:39 GMT
Accept-Ranges: bytes
Cache-Control: max-age=3600
Expires: Wed, 22 Jul 2009 07:29:58 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 27
Connection: close
Content-Type: text/plain; charset=UTF-8
&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;`&#96;``
</pre>
<h2>.htaccess Directives</h2>
<p>AcceptFilter, AcceptMutex, AcceptPathInfo, AccessFileName, Action, AddAlt, AddAltByEncoding, AddAltByType, AddCharset, AddDefaultCharset, AddDescription, AddEncoding, AddHandler, AddIcon, AddIconByEncoding, AddIconByType, AddInputFilter, AddLanguage, AddModuleInfo, AddOutputFilter, AddOutputFilterByType, AddType, Alias, AliasMatch, AllowCONNECT, AllowEncodedSlashes, AllowOverride, Anonymous, Anonymous_Authoritative, Anonymous_LogEmail, Anonymous_MustGiveEmail, Anonymous_NoUserID, Anonymous_NoUserId, Anonymous_VerifyEmail, AssignUserId, AuthAuthoritative, AuthBasicAuthoritative, AuthBasicProvider, AuthDBDUserPWQuery, AuthDBDUserRealmQuery, AuthDBM, AuthDBMAuthoritative, AuthDBMGroupFile, AuthDBMType, AuthDBMUserFile, AuthDefaultAuthoritative, AuthDigestAlgorithm, AuthDigestDomain, AuthDigestFile, AuthDigestGroupFile, AuthDigestNcCheck, AuthDigestNonceFormat, AuthDigestNonceLifetime, AuthDigestProvider, AuthDigestQop, AuthDigestShmemSize, AuthGroupFile, AuthLDAPAuthzEnabled, AuthLDAPBindDN, AuthLDAPBindON, AuthLDAPBindPassword, AuthLDAPCharsetConfig, AuthLDAPCompareDNOnServer, AuthLDAPDereferenceAliases, AuthLDAPEnabled, AuthLDAPFrontPageHack, AuthLDAPGroupAttribute, AuthLDAPGroupAttributeIsDN, AuthLDAPRemoteUserAttribute, AuthLDAPRemoteUserIsDN, AuthLDAPStartTLS, AuthLDAPURL, AuthLDAPUrl, AuthName, AuthType, AuthUserFile, AuthzDBMAuthoritative, AuthzDBMType, AuthzDefaultAuthoritative, AuthzGroupFileAuthoritative, AuthzLDAPAuthoritative, AuthzOwnerAuthoritative, AuthzUserAuthoritative, BS2000Account, BalancerMember, BrowserMatch, BrowserMatchNoCase, BufferedLogs, CGIMapExtension, CacheDefaultExpire, CacheDirLength, CacheDirLevels, CacheDisable, CacheEnable, CacheExpiryCheck, CacheFile, CacheForceCompletion, CacheGcClean, CacheGcDaily, CacheGcInterval, CacheGcMemUsage, CacheGcUnused, CacheIgnoreCacheControl, CacheIgnoreHeaders, CacheIgnoreNoLastMod, CacheLastModifiedFactor, CacheMaxExpire, CacheMaxFileSize, CacheMaxStreamingBuffer, CacheMinFileSize, CacheNegotiatedDocs, CacheRoot, CacheSize, CacheStoreNoStore, CacheStorePrivate, CacheTimeMargin, CharsetDefault, CharsetOptions, CharsetSourceEnc, CheckCaseOnly, CheckSpelling, ChildPerUserId, ContentDigest, CookieDomain, CookieExpires, CookieLog, CookieName, CookieStyle, CookieTracking, CoreDumpDirectory, CustomLog, DAV, DAVDepthInfinity, DAVGenericLockDB, DAVMinTimeout, DBDExptime, DBDKeep, DBDMax, DBDMin, DBDParams, DBDPersist, DBDPrepareSQL, DBDriver, Dav, DavDepthInfinity, DavGenericLockDB, DavLockDB, DavMinTimeout, DefaultIcon, DefaultLanguage, DefaultType, DeflateBufferSize, DeflateCompressionLevel, DeflateFilterNote, DeflateMemLevel, DeflateWindowSize, Directory, DirectoryIndex, DirectoryMatch, DirectorySlash, DocumentRoot, DumpIOInput, DumpIOOutput, EnableExceptionHook, EnableMMAP, EnableSendfile, ErrorDocument, ErrorLog, Example, ExpiresActive, ExpiresByType, ExpiresDefault, ExtFilterDefine, ExtFilterOptions, ExtendedStatus, FancyIndexing, FileETag, Files, FilesMatch, FilterChain, FilterDeclare, FilterProtocol, FilterProvider, FilterTrace, ForceLanguagePriority, ForceType, ForensicLog, GprofDir, GracefulShutdownTimeout, Group, Header, HeaderName, HostNameLookups, HostnameLookups, ISAIPFakeAsync, ISAPIAppendLogToErrors, ISAPIAppendLogToQuery, ISAPICacheFile, ISAPIFakeAsync, ISAPILogNotSupported, ISAPIReadAheadBuffer, IdentityCheck, IdentityCheckTimeout, IfDefine, IfModule, IfVersion, ImapBase, ImapDefault, ImapMenu, Include, IndexIgnore, IndexOptions, IndexOrderDefault, IndexStyleSheet, KeepAlive, KeepAliveTimeout, LDAPCacheEntries, LDAPCacheTTL, LDAPCertDBPath, LDAPConnectionTimeout, LDAPOpCacheEntries, LDAPOpCacheTTL, LDAPSharedCacheFile, LDAPSharedCacheSize, LDAPTrustedClientCert, LDAPTrustedGlobalCert, LDAPTrustedMode, LDAPVerifyServerCert, LanguagePriority, Limit, LimitExcept, LimitInternalRecursion, LimitRequestBody, LimitRequestFields, LimitRequestFieldsize, LimitRequestLine, LimitXMLRequestBody, Listen, ListenBacklog, LoadFile, LoadModule, Location, LocationMatch, LockFile, LogFormat, LogLevel, MCacheMaxObjectCount, MCacheMaxObjectSize, MCacheMaxStreamingBuffer, MCacheMinObjectSize, MCacheRemovalAlgorithm, MCacheSize, MMapFile, MaxClients, MaxKeepAliveRequests, MaxMemFree, MaxRequestsPerChild, MaxSpareServers, MaxSpareThreads, MaxSpareThreadsPerChild, MaxThreads, MetaDir, MetaFiles, MetaSuffix, MimeMagicFile, MinSpareServers, MinSpareThreads, ModMimeUsePathInfo, MultiviewsMatch, NWSSLTrustedCerts, NWSSLUpgradeable, NameVirtualHost, NoProxy, NumServers, Options, PassEnv, PerlAccessHandler, PerlAuthenHandler, PerlAuthzHandler, PerlChildExitHandler, PerlChildInitHandler, PerlCleanupHandler, PerlDispatchHandler, PerlFixupHandler, PerlFreshRestart, PerlHandler, PerlHeaderParserHandler, PerlInitHandler, PerlLogHandler, PerlModule, PerlPassEnv, PerlPostReadRequestHandler, PerlRequire, PerlRestartHandler, PerlSendHeader, PerlSetEnv, PerlSetVar, PerlSetupEnv, PerlTaintCheck, PerlTransHandler, PerlTypeHandler, PerlWarn, PidFile, Port, Protocol, ProtocolEcho, Proxy, ProxyBadHeader, ProxyBlock, ProxyDomain, ProxyErrorOverride, ProxyFtpDirCharset, ProxyIOBufferSize, ProxyMatch, ProxyMaxForwards, ProxyPass, ProxyPassInterpolateEnv, ProxyPassMatch, ProxyPassReverse, ProxyPassReverseCookieDomain, ProxyPassReverseCookiePath, ProxyPreserveHost, ProxyReceiveBufferSize, ProxyRemote, ProxyRemoteMatch, ProxyRequests, ProxySet, ProxyStatus, ProxyTimeout, ProxyVia, RLimitCPU, RLimitMEM, RLimitNPROC, ReadmeName, Redirect, RedirectMatch, RedirectPermanent, RedirectTemp, RemoveCharset, RemoveEncoding, RemoveHandler, RemoveInputFilter, RemoveLanguage, RemoveOutputFilter, RemoveType, RequestHeader, Require, RewriteBase, RewriteCond, RewriteEngine, RewriteLock, RewriteLog, RewriteLogLevel, RewriteMap, RewriteOptions, RewriteRule, SSIAccessEnable, SSIEndTag, SSIErrorMsg, SSIStartTag, SSITimeFormat, SSIUndefinedEcho, SSLCACertificateFile, SSLCACertificatePath, SSLCADNRequestFile, SSLCADNRequestPath, SSLCARevocationFile, SSLCARevocationPath, SSLCertificateChainFile, SSLCertificateFile, SSLCertificateKeyFile, SSLCipherSuite, SSLCryptoDevice, SSLEngine, SSLHonorCipherOrder, SSLLog, SSLLogLevel, SSLMutex, SSLOptions, SSLPassPhraseDialog, SSLProtocol, SSLProxyCACertificateFile, SSLProxyCACertificatePath, SSLProxyCARevocationFile, SSLProxyCARevocationPath, SSLProxyCipherSuite, SSLProxyEngine, SSLProxyMachineCertificateFile, SSLProxyMachineCertificatePath, SSLProxyProtocol, SSLProxyVerify, SSLProxyVerifyDepth, SSLRandomSeed, SSLRequire, SSLRequireSSL, SSLSessionCache, SSLSessionCacheTimeout, SSLUserName, SSLVerifyClient, SSLVerifyDepth, Satisfy, ScoreBoardFile, Script, ScriptAlias, ScriptAliasMatch, ScriptInterpreterSource, ScriptLog, ScriptLogBuffer, ScriptLogLength, ScriptStock, SecureListen, SendBufferSize, ServerAdmin, ServerAlias, ServerLimit, ServerName, ServerPath, ServerRoot, ServerSignature, ServerTokens, SetEnv, SetEnvIf, SetEnvIfNoCase, SetHandler, SetInputFilter, SetOutputFilter, StartServers, StartThreads, Substitute, SuexecUserGroup, ThreadLimit, ThreadStackSize, ThreadsPerChild, TimeOut, Timeout, TraceEnable, TransferLog, TypeAuthDBMUserFile, TypesConfig, UnsetEnv, UseCanonicalName, UseCanonicalPhysicalPort, User, UserDir, VirtualDocumentRoot, VirtualDocumentRootIP, VirtualHost, VirtualScriptAlias, VirtualScriptAliasIP, Win32DisableAcceptEx, XBitHack, allow, deny, order, php_admin_flag, php_admin_value, php_flag, php_value</p>
<p class="anote">You can view the <a href="http://www.askapache.com/htaccess/htaccess-security-block-spam-hackers.html">plugins home page</a>, <a href="http://www.askapache.com/wordpress/htaccess-password-protect.html#aadl">old</a>, or <a href="http://wordpress.org/extend/plugins/askapache-password-protect/">view it on the wordpress.org site</a>.</p>
<p><a href="http://www.askapache.com/wordpress/an-askapache-plugin-upgrade-to-rule-them-all.html">An AskApache Plugin Upgrade to Rule them All</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/an-askapache-plugin-upgrade-to-rule-them-all.html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AskApache Debug Viewer Plugin for WordPress</title>
		<link>http://www.askapache.com/wordpress/debug-viewer-plugin.html</link>
		<comments>http://www.askapache.com/wordpress/debug-viewer-plugin.html#comments</comments>
		<pubDate>Mon, 06 Apr 2009 03:53:31 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[wordpress development]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=2502</guid>
		<description><![CDATA[<p><a class="IFL" href='/wp-content/uploads/2009/04/screenshot-1.png' title='screenshot-1'><img src="/wp-content/uploads/2009/04/screenshot-1-350x306.png" alt="screenshot-1" title="screenshot-1" width="350" height="306" /></a><strong>The story behind this plugin is sorta wack</strong>, but in a good way :).  While doing tons of security research on permissions, authorization, access, etc.. for the <a href="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html">Password Protection plugin</a> (<em><a href="http://www.askapache.com/htaccess/password-protection-plugin-status.html">still being worked on</a></em>), I needed to have unheard of debugging capabilities while working on the plugin on the various websites, webhosts, and test servers that I use to test in different environments.  So I hacked together a bunch of php code that helped me debug, actually I pretty much went overkill and tried to get as much debugging info as programmatically possible, and it ended up being so much code that I took it out of my Password Protection code and made it its own plugin.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a href="#php-debug-screenshots">Screen Shots</a> | <a href="#php-debug-functions">PHP Debug Functions</a></p>
<p><a class="IFL" href='/wp-content/uploads/2009/04/screenshot-1.png' title='screenshot-1'><img src="/wp-content/uploads/2009/04/screenshot-1-350x306.png" alt="screenshot-1" title="screenshot-1" width="350" height="306" /></a><strong>The story behind this plugin is sorta wack</strong>, but in a good way :).  While doing tons of security research on permissions, authorization, access, etc.. for the <a href="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html">Password Protection plugin</a> (<em><a href="http://www.askapache.com/htaccess/password-protection-plugin-status.html">still being worked on</a></em>), I needed to have unheard of debugging capabilities while working on the plugin on the various websites, webhosts, and test servers that I use to test in different environments.  So I hacked together a bunch of php code that helped me debug, actually I pretty much went overkill and tried to get as much debugging info as programmatically possible, and it ended up being so much code that I took it out of my Password Protection code and made it its own plugin.<br class="C" /></p>
<p>I&#8217;ve been using it for several months now while working on a plugin or diagnosing some issue, and decided that I&#8217;d share it with everyone.  Hopefully it will help other plugin authors and php programmers in general to start writing more robust and error-proof code, which would in turn help me!  To help those not using WordPress, I&#8217;ve included most of the debugging functions below, but you&#8217;ll need the AskApacheDebug class for them to work.  Hope you find it useful!  I do.  <a href="http://wordpress.org/extend/plugins/askapache-debug-viewer/">Download AskApache Debug Viewer</a></p>
<hr class="C" />
<h2><a name="php-debug-screenshots" id="php-debug-screenshots"></a>Screenshots and Debug Output</h2>
<p>The plugin outputs the debugging info in the admin footer by hooking into the &#8216;in_admin_footer&#8217; action.<br /><a href='/wp-content/uploads/2009/04/screenshot-2.png' title='screenshot-2'><img src="/wp-content/uploads/2009/04/screenshot-2.png" alt="" title="screenshot-2" /></a></p>
<p><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-3.png' title='screenshot-3'><img width="341" height="350" src="/wp-content/uploads/2009/04/screenshot-3-341x350.png" alt="" title="screenshot-3" /></a><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-4.png' title='screenshot-4'><img width="350" height="170" src="/wp-content/uploads/2009/04/screenshot-4-350x170.png" alt="" title="screenshot-4" /></a><br class="C" /></p>
<p><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-5.png' title='screenshot-5'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-5-350x285.png" alt="" title="screenshot-5" /></a><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-6.png' title='screenshot-6'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-6-350x285.png" alt="" title="screenshot-6" /></a><br class="C" /></p>
<p><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-7.png' title='screenshot-7'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-7-350x285.png" alt="" title="screenshot-7" /></a><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-8.png' title='screenshot-8'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-8-350x285.png" alt="" title="screenshot-8" /></a><br class="C" /></p>
<p><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-9.png' title='screenshot-9'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-9-350x285.png" alt="" title="screenshot-9" /></a><a class="FL" style="border-right:5px solid #FFF;" href='/wp-content/uploads/2009/04/screenshot-10.png' title='screenshot-10'><img width="350" height="285" src="/wp-content/uploads/2009/04/screenshot-10-350x285.png" alt="" title="screenshot-10" /></a><br class="C" /></p>
<h2><a name="php-debug-functions" id="php-debug-functions"></a>PHP Debugging Functions</h2>
<p>Ok so for those interested more in the php flavor, here are a few of the functions that produce the debugging output.  I&#8217;ll start with my customized _stat function, which took a lot of research to write, but you can read that story at <a href="http://www.askapache.com/security/chmod-stat.html">Chmod, Umask, Stat, Fileperms, and File Permissions</a>.</p>
<pre>
function _stat($fl)
{
  static $ftypes = false;
  if (!$ftypes)
  {
    $this-&gt;logg(__FUNCTION__ . &#039;:&#039; . __LINE__);
    $ftypes = array(S_IFSOCK =&gt; &#039;ssocket&#039;, S_IFLNK =&gt; &#039;llink&#039;, S_IFREG =&gt; &#039;-file&#039;, S_IFBLK =&gt; &#039;bblock&#039;, S_IFDIR =&gt; &#039;ddir&#039;, S_IFCHR =&gt; &#039;cchar&#039;, S_IFIFO =&gt; &#039;pfifo&#039;);
  }
&nbsp;
  $s = $ss = array();
  if (($ss = stat($fl)) === false) return $this-&gt;logg(__FUNCTION__ . &#039;:&#039; . __LINE__ . " Couldnt stat {$fl}", 0);
  $p = $ss[&#039;mode&#039;];
  $t = decoct($p &#038; S_IFMT);
  $q = octdec($t);
  $type = (array_key_exists($q, $ftypes)) ? substr($ftypes[$q], 0, 1) : &#039;?&#039;;
$s = array(
&#039;filename&#039; =&gt; $fl,
&nbsp;
&#039;human&#039; =&gt; ($type .
(($p &#038; S_IRUSR) ? &#039;r&#039; : &#039;-&#039;) . (($p &#038; S_IWUSR) ? &#039;w&#039; : &#039;-&#039;) . (($p &#038; S_ISUID) ? (($p &#038; S_IXUSR) ? &#039;s&#039; : &#039;S&#039;) : (($p &#038; S_IXUSR) ? &#039;x&#039; : &#039;-&#039;)) .
(($p &#038; S_IRGRP) ? &#039;r&#039; : &#039;-&#039;) . (($p &#038; S_IWGRP) ? &#039;w&#039; : &#039;-&#039;) . (($p &#038; S_ISGID) ? (($p &#038; S_IXGRP) ? &#039;s&#039; : &#039;S&#039;) : (($p &#038; S_IXGRP) ? &#039;x&#039; : &#039;-&#039;)) .
(($p &#038; S_IROTH) ? &#039;r&#039; : &#039;-&#039;) . (($p &#038; S_IWOTH) ? &#039;w&#039; : &#039;-&#039;) . (($p &#038; S_ISVTX) ? (($p &#038; S_IXOTH) ? &#039;t&#039; : &#039;T&#039;) : (($p &#038; S_IXOTH) ? &#039;x&#039; : &#039;-&#039;))),
&#039;octal&#039; =&gt; sprintf("%o", ($ss[&#039;mode&#039;] &#038; 007777)),
&#039;hex&#039; =&gt; sprintf("0x%x", $ss[&#039;mode&#039;]),
&#039;decimal&#039; =&gt; sprintf("%d", $ss[&#039;mode&#039;]),
&#039;binary&#039; =&gt; sprintf("%b", $ss[&#039;mode&#039;]),
&#039;base_convert&#039; =&gt; base_convert($ss[&#039;mode&#039;],10,8),
&#039;fileperms&#039; =&gt; fileperms($fl),
&#039;mode&#039; =&gt; $p,
&nbsp;
&#039;type_octal&#039; =&gt; sprintf("%07o", $q),  &#039;fileuid&#039; =&gt; $ss[&#039;uid&#039;],
&nbsp;
&#039;type&#039; =&gt; $type,
&#039;filegid&#039; =&gt; $ss[&#039;gid&#039;],
&#039;owner_name&#039; =&gt; $this-&gt;get_posix_info(&#039;user&#039;, $ss[&#039;uid&#039;],
&#039;name&#039;),
&#039;group_name&#039; =&gt; $this-&gt;get_posix_info(&#039;group&#039;, $ss[&#039;gid&#039;],
&#039;name&#039;),
&#039;dirname&#039; =&gt; dirname($fl),
&#039;is_file&#039; =&gt; is_file($fl) ? 1 : 0,
&#039;is_dir&#039; =&gt; is_dir($fl) ? 1 : 0,
&#039;is_link&#039; =&gt; is_link($fl) ? 1 : 0,
&#039;is_readable&#039; =&gt; is_readable($fl) ? 1 : 0,
&#039;is_writable&#039; =&gt;
is_writable($fl) ? 1 : 0,&#039;device&#039; =&gt; $ss[&#039;dev&#039;],
&#039;device_number&#039; =&gt; $ss[&#039;rdev&#039;],
&#039;inode&#039; =&gt; $ss[&#039;ino&#039;],
&#039;link_count&#039; =&gt; $ss[&#039;nlink&#039;],
&#039;size&#039; =&gt; $ss[&#039;size&#039;],
&#039;blocks&#039; =&gt; $ss[&#039;blocks&#039;],
&#039;block_size&#039; =&gt; $ss[&#039;blksize&#039;],
&#039;accessed&#039; =&gt; date(&#039;Y M D H:i:s&#039;, $ss[&#039;atime&#039;]),
&#039;modified&#039; =&gt; date(&#039;Y M D H:i:s&#039;, $ss[&#039;mtime&#039;]),
&#039;created&#039; =&gt; date(&#039;Y M D H:i:s&#039;, $ss[&#039;ctime&#039;]),
&#039;mtime&#039; =&gt; $ss[&#039;mtime&#039;], &#039;atime&#039; =&gt; $ss[&#039;atime&#039;],
&#039;ctime&#039; =&gt; $ss[&#039;ctime&#039;], );
  if (is_link($fl)) $s[&#039;link_to&#039;] = readlink($fl);
  if (realpath($fl) != $fl) $s[&#039;real_filename&#039;] = realpath($fl);
&nbsp;
  return $s;
}
</pre>
<h3>get_debug_functions</h3>
<p>These are various security and user related information.  Nice.</p>
<pre>
function get_debug_functions($vb=false)
{
  $functions=$oa=array();
  $functions = array(
&#039;PHP script Process ID&#039; =&gt; &#039;getmypid&#039;,
&#039;PHP script owners UID&#039; =&gt; &#039;getmyuid&#039;,
&#039;php_sapi_name&#039; =&gt; &#039;php_sapi_name&#039;,
&#039;PHP Uname&#039; =&gt; &#039;php_uname&#039;,
&#039;Zend Version&#039; =&gt; &#039;zend_version&#039;,
&#039;PHP INI Loaded&#039; =&gt; &#039;php_ini_loaded_file&#039;,
&#039;Current Working Directory&#039; =&gt; &#039;getcwd&#039;,
&#039;Last Mod&#039; =&gt; &#039;getlastmod&#039;,
&#039;Script Inode&#039; =&gt; &#039;getmyinode&#039;,
&#039;Script GID&#039; =&gt; &#039;getmygid&#039;,
&#039;Script Owner&#039; =&gt; &#039;get_current_user&#039;,
&#039;Get Rusage&#039; =&gt; &#039;getrusage&#039;,
&#039;Error Reporting&#039; =&gt; &#039;error_reporting&#039;,
&#039;Path name of controlling terminal&#039; =&gt; &#039;posix_ctermid&#039;,
&#039;Error number set by the last posix function that failed&#039; =&gt; &#039;posix_get_last_error&#039;,
&#039;Pathname of current directory&#039; =&gt; &#039;posix_getcwd&#039;,
&#039;posix_getpid&#039; =&gt; &#039;posix_getpid&#039;,
&#039;posix_uname&#039; =&gt; &#039;posix_uname&#039;,
&#039;posix_times&#039; =&gt;&#039;posix_times&#039;,
&#039;posix_errno&#039; =&gt; &#039;posix_errno&#039;,
&#039;Effective group ID of the current process&#039; =&gt; &#039;posix_getegid&#039;,
&#039;Effective user ID of the current process&#039; =&gt; &#039;posix_geteuid&#039;,
&#039;Real group ID of the current process&#039; =&gt; &#039;posix_getgid&#039;,
&#039;Group set of the current process&#039; =&gt; &#039;posix_getgroups&#039;,
&#039;Login name&#039; =&gt; &#039;posix_getlogin&#039;,
&#039;Current process group identifier&#039; =&gt; &#039;posix_getpgrp&#039;,
&#039;Current process identifier&#039; =&gt; &#039;posix_getpid&#039;,
&#039;Parent process identifier&#039; =&gt; &#039;posix_getppid&#039;,
&#039;System Resource limits&#039; =&gt; &#039;posix_getrlimit&#039;,
&#039;Return the real user ID of the current process&#039; =&gt; &#039;posix_getuid&#039;,
&#039;Magic Quotes GPC&#039; =&gt; &#039;get_magic_quotes_gpc&#039;,
&#039;Magic Quotes Runtime&#039; =&gt; &#039;get_magic_quotes_runtime&#039;, );
&nbsp;
  foreach ($functions as $title =&gt; $func_name) {
    $val = &#039;&#039;;
    if ( ( $this-&gt;checkfunction($func_name) &#038;&#038; ($val = $func_name()) !== false) ){
      if (empty($val)) $val=$func_name;
      $oa[$title] = $val;
    }
  }
&nbsp;
  return $oa;
}
</pre>
<h3>get_debug_permissions</h3>
<p>This is a function designed to get as much information about file/user/group permissions as possible.</p>
<pre>
function get_debug_permissions($vb=false)
{
  $oa=array();
&nbsp;
  $user_info = $this-&gt;get_posix_info(&#039;user&#039;);
  $group_info = $this-&gt;get_posix_info(&#039;group&#039;);
&nbsp;
$functions = array(
&#039;Real Group ID&#039; =&gt; posix_getgid(),
&#039;Effective Group ID&#039; =&gt; posix_getegid(),
&#039;Parent Process ID&#039; =&gt; posix_getppid(),
&#039;Parent Process Group ID&#039; =&gt; posix_getpgid(posix_getppid()),
&#039;Real Process ID&#039; =&gt; posix_getpid(),
&#039;Real Process Group ID&#039; =&gt; posix_getpgid(posix_getpid()),
&#039;Process Effective User ID&#039; =&gt; posix_geteuid(),
&#039;Process Owner Username&#039; =&gt; $user_info[&#039;name&#039;],
&#039;File Owner Username&#039; =&gt; get_current_user(),
&#039;User Info&#039; =&gt; print_r($user_info, 1),
&#039;Group Info&#039; =&gt; print_r($group_info, 1),
&#039;RealPath&#039;  =&gt; realpath(__FILE__),
&#039;SAPI Name&#039; =&gt; (function_exists(&#039;php_sapi_name&#039;)) ? print_r(php_sapi_name(), 1) : &#039;&#039;,
&#039;Posix Process Owner&#039; =&gt; print_r(posix_getpwuid(posix_geteuid()), 1),
&#039;Scanned Ini&#039; =&gt; (function_exists(&#039;php_ini_scanned_files&#039;)) ? str_replace("\n", "", php_ini_scanned_files()) : &#039;&#039;,
&#039;PHP.ini Path&#039; =&gt; get_cfg_var(&#039;cfg_file_path&#039;),
&#039;Sendmail Path&#039; =&gt; get_cfg_var(&#039;sendmail_path&#039;),
&#039;Info about a group by group id&#039; =&gt; posix_getgrgid(posix_getegid()),
&#039;Process group id for Current process&#039; =&gt; posix_getpgid(posix_getpid()),
&#039;Process group id for Parent process&#039; =&gt; posix_getpgid(posix_getppid()),
&#039;Process group id of the session leader.&#039; =&gt; posix_getsid(posix_getpid()),
&#039;Info about a user by username&#039; =&gt; posix_getpwnam(get_current_user()),
&#039;Info about a user by user id&#039; =&gt; posix_getpwuid(posix_geteuid()),
&#039;Apache Version&#039; =&gt; (function_exists(&#039;apache_get_version&#039;)) ? print_r(apache_get_version(), 1) : &#039;&#039;,
&#039;Apache Modules&#039; =&gt; (function_exists(&#039;apache_get_modules&#039;)) ? print_r(apache_get_modules(), 1) : &#039;&#039;,
&#039;PHP_LOGO_GUI&#039; =&gt; php_logo_guid(),
&#039;ZEND_LOGO_GUI&#039; =&gt; zend_logo_guid()
);
&nbsp;
  foreach ($functions as $title =&gt; $v) $oa[$title] = $v;
&nbsp;
  return $oa;
}
</pre>
<h3>get_debug_defined</h3>
<p>This gets all the defined constants, if verbose it gets more and gets the values for each.</p>
<pre>
function get_debug_defined($vb=false)
{
  $oa=array();
  foreach ((array)@get_defined_constants() as $k =&gt; $v){if (!$vb &#038;&#038; in_array($k, array(&#039;ABSPATH&#039;, &#039;WP_ADMIN&#039;))) $vb = true;  if($vb)$oa[$k]=$v;}
&nbsp;
  foreach (
  array(&#039;WP_TEMP_DIR&#039;, &#039;WP_SITEURL&#039;, &#039;WP_HOME&#039;, &#039;ABSPATH&#039;, &#039;WP_CONTENT_URL&#039;,
  &#039;WP_CONTENT_DIR&#039;, &#039;WP_PLUGIN_DIR&#039;, &#039;WP_PLUGIN_URL&#039;, &#039;WP_LANG_DIR&#039;, &#039;TEMPLATEPATH&#039;,
  &#039;STYLESHEETPATH&#039;, &#039;WPINC&#039;, &#039;COOKIEPATH&#039;, &#039;SITECOOKIEPATH&#039;, &#039;ADMIN_COOKIE_PATH&#039;,
  &#039;PLUGINS_COOKIE_PATH&#039;, &#039;PHP_SAPI&#039;, &#039;PHP_OS&#039;, &#039;PHP_VERSION&#039;
  ) as $def) if (defined($def) &#038;&#038; $val = constant($def) &#038;&#038; !empty($val)) $oa[$def] = $val;
&nbsp;
  return $oa;
}
</pre>
<h3>get_debug_inis</h3>
<p>This function gets the values of your php ini, if verbose it gets them all and shows the currently used value instead of both the global and local.</p>
<pre>
function get_debug_inis($vb=false)
{
  $oa=array();
&nbsp;
  foreach (array(&#039;Error Log&#039; =&gt; &#039;error_log&#039;,
&#039;Session Data Path&#039; =&gt; &#039;session.save_path&#039;,
&#039;Upload Tmp Dir&#039; =&gt; &#039;upload_tm_p_dir&#039;,
&#039;Include Path&#039; =&gt; &#039;include_path&#039;,
&#039;Memory Limit&#039; =&gt; &#039;memory_limit&#039;,
&#039;Max Execution Time&#039; =&gt; &#039;max_execution_time&#039;,
&#039;Display Errors&#039; =&gt; &#039;display_errors&#039;,
&#039;Allow url fopen&#039; =&gt; &#039;allow_url_fopen&#039;,
&#039;Disabled Functions&#039; =&gt; &#039;disable_functions&#039;,
&#039;Safe Mode&#039; =&gt; &#039;safe_mode&#039;,
&#039;Open Basedir&#039; =&gt; &#039;open_basedir&#039;,
&#039;File Uploads&#039; =&gt; &#039;file_uploads&#039;,
&#039;Max Upload Filesize&#039; =&gt; &#039;upload_max_filesize&#039;,
&#039;Max POST Size&#039; =&gt; &#039;post_max_size&#039;,
&#039;Open Basedir&#039; =&gt; &#039;open_basedir&#039;) as $title =&gt; $ini_name) if (($val = &#039;&#039; &#038;&#038; $val = strval(ini_get($ini_name))) !== false &#038;&#038; !empty($val)) $oa[$title] = $val;
&nbsp;
  if($vb!==false){
    foreach ((array)@ini_get_all() as $k =&gt; $v) $oa[$k] = (($v[&#039;global_value&#039;] == $v[&#039;local_value&#039;]) ? $v[&#039;global_value&#039;] : $v);
  }
  return $oa;
}
</pre>
<h3>get_debug_phpinfo</h3>
<p>I&#8217;m particularly proud of this function because the preg_replace was tough and the result is a perfect array of values returned by the phpinfo command.</p>
<pre>
function get_debug_phpinfo()
{
  $oa=array();
  ob_start();
  phpinfo(-1);
  $oa = preg_replace(array(&#039;#^.*&lt;body&gt;(.*)&lt;/body&gt;.*$#ms&#039;, &#039;#&lt;h2&gt;PHP License&lt;/h2&gt;.*$#ms&#039;, &#039;#&lt;h1&gt;Configuration&lt;/h1&gt;#&#039;, "#\r?\n#", "#&lt;/(h1|h2|h3|tr)&gt;#", &#039;# +&lt;#&#039;, "#[ \t]+#", &#039;#&nbsp;#&#039;, &#039;#  +#&#039;, &#039;# class=".*?"#&#039;, &#039;%&#039;%&#039;, &#039;#&lt;tr&gt;(?:.*?)" src="(?:.*?)=(.*?)" alt="PHP Logo" /&gt;&lt;/a&gt;&#039; . &#039;&lt;h1&gt;PHP Version (.*?)&lt;/h1&gt;(?:\n+?)&lt;/td&gt;&lt;/tr&gt;#&#039;,
    &#039;#&lt;h1&gt;&lt;a href="(?:.*?)?=(.*?)"&gt;PHP Credits&lt;/a&gt;&lt;/h1&gt;#&#039;, &#039;#&lt;tr&gt;(?:.*?)" src="(?:.*?)=(.*?)"(?:.*?)Zend Engine (.*?),(?:.*?)&lt;/tr&gt;#&#039;, "#  +#", &#039;#&lt;tr&gt;#&#039;, &#039;#&lt;/tr&gt;#&#039;), array(&#039;$1&#039;, &#039;&#039;, &#039;&#039;, &#039;&#039;, &#039;&lt;/$1&gt;&#039; . "\n", &#039;&lt;&#039;, &#039; &#039;, &#039; &#039;, &#039; &#039;, &#039;&#039;, &#039; &#039;, &#039;&lt;h2&gt;PHP Configuration&lt;/h2&gt;&#039; . "\n" . &#039;&lt;tr&gt;&lt;td&gt;PHP Version&lt;/td&gt;&lt;td&gt;$2&lt;/td&gt;&lt;/tr&gt;&#039; . "\n" . &#039;&lt;tr&gt;&lt;td&gt;PHP Egg&lt;/td&gt;&lt;td&gt;$1&lt;/td&gt;&lt;/tr&gt;&#039;,
    &#039;&lt;tr&gt;&lt;td&gt;PHP Credits Egg&lt;/td&gt;&lt;td&gt;$1&lt;/td&gt;&lt;/tr&gt;&#039;, &#039;&lt;tr&gt;&lt;td&gt;Zend Engine&lt;/td&gt;&lt;td&gt;$2&lt;/td&gt;&lt;/tr&gt;&#039; . "\n" . &#039;&lt;tr&gt;&lt;td&gt;Zend Egg&lt;/td&gt;&lt;td&gt;$1&lt;/td&gt;&lt;/tr&gt;&#039;, &#039; &#039;, &#039;%S%&#039;, &#039;%E%&#039;), ob_get_clean());
  $sections = explode(&#039;&lt;h2&gt;&#039;, strip_tags($oa, &#039;&lt;h2&gt;&lt;th&gt;&lt;td&gt;&#039;));
  unset($sections[0]);
  $oa = array();
  foreach ($sections as $section)
  {
    $n = substr($section, 0, strpos($section, &#039;&lt;/h2&gt;&#039;));
    preg_match_all(&#039;#%S%(?:&lt;td&gt;(.*?)&lt;/td&gt;)?(?:&lt;td&gt;(.*?)&lt;/td&gt;)?(?:&lt;td&gt;(.*?)&lt;/td&gt;)?%E%#&#039;, $section, $askapache, PREG_SET_ORDER);
    foreach ($askapache as $m) $oa[$n][$m[1]] = (!isset($m[3]) || $m[2] == $m[3]) ? $m[2] : array_slice($m, 2);
  }
  return $oa;
}
</pre>
<h3>get_debug_included</h3>
<p>Gets a list of all the files included by php, if verbose it also super-stats them.</p>
<pre>
function get_debug_included($vb=false)
{
  $oa=array();
  foreach((array)@get_included_files() as $k=&gt;$v) $oa[$v]=($vb===false) ? &#039;&#039; : $this-&gt;_stat($v);
  return $oa;
}
</pre>
<h3>get_debug_classes</h3>
<p>Gets a list of predefined classes declared in your php instance, if verbose it gets EVERY class and also gets the methods for each.</p>
<pre>
function get_debug_classes($vb=false)
{
  $classes=$oa=array();
  $classes= ($vb!==false) ? (array)@get_declared_classes() : array(&#039;WP&#039;,&#039;WP_Error&#039;,&#039;Walker&#039;,&#039;WP_Ajax_Response&#039;,&#039;wpdb&#039;,&#039;WP_Object_Cache&#039;,&#039;WP_Query&#039;,&#039;WP_Rewrite&#039;,&#039;WP_Locale&#039;);
  foreach ($classes as $k)  $oa[$k] = @get_class_methods($k);

  return $oa;
}
</pre>
<h3>get_debug_globals</h3>
<p>This function tries to get the values of every known (past and present) global variable in php.</p>
<pre>
function get_debug_globals($vb=false)
{
  $oa=array();
&nbsp;
  $globs =
  array(
  &#039;GET&#039;     =&gt; isset( $_GET )?$_GET:&#039;&#039;,
  &#039;POST&#039;    =&gt; isset( $_POST )?$_POST:&#039;&#039;,
  &#039;COOKIE&#039;  =&gt; isset( $_COOKIE )?$_COOKIE:&#039;&#039;,
  &#039;SESSION&#039;   =&gt; isset( $_SESSION )?$_SESSION:&#039;&#039;,
  &#039;ENV&#039;     =&gt; isset( $_ENV )?$_ENV:&#039;&#039;,
  &#039;FILES&#039;     =&gt; isset( $_FILES )?$_FILES:&#039;&#039;,
  &#039;SERVER&#039;  =&gt; isset( $_SERVER )?$_SERVER:&#039;&#039;,
  &#039;SERVER&#039;  =&gt; isset( $_SERVER )?$_SERVER:&#039;&#039;,
  &#039;UPLOAD&#039;  =&gt; function_exists(&#039;wp_upload_dir&#039;) ? wp_upload_dir():&#039;&#039;,
  &#039;REQUEST&#039;   =&gt; isset( $_REQUEST )?$_REQUEST:&#039;&#039;,
  &#039;HTTP_POST_FILES&#039;   =&gt; isset( $HTTP_POST_FILES )?$HTTP_POST_FILES:&#039;&#039;,
  &#039;HTTP_POST_VARS&#039;    =&gt; isset( $HTTP_POST_VARS )?$HTTP_POST_VARS:&#039;&#039;,
  &#039;HTTP_SERVER_VARS&#039;  =&gt;  isset( $HTTP_SERVER_VARS )?$HTTP_SERVER_VARS:&#039;&#039;,
  &#039;HTTP_RAW_POST_DATA&#039; =&gt; isset( $HTTP_RAW_POST_DATA )?$HTTP_RAW_POST_DATA:&#039;&#039;,
  &#039;HTTP_GET_VARS&#039;     =&gt; isset( $HTTP_GET_VARS )?$HTTP_GET_VARS:&#039;&#039;,
  &#039;HTTP_COOKIE_VARS&#039;  =&gt;  isset( $HTTP_COOKIE_VARS )?$HTTP_COOKIE_VARS:&#039;&#039;,
  &#039;HTTP_ENV_VARS&#039;     =&gt; isset( $HTTP_ENV_VARS )?$HTTP_ENV_VARS:&#039;&#039;,
  );
  foreach ($globs as $k =&gt; $v) if (isset($v) &#038;&#038; sizeof($v) &gt; 0) $oa[$k] = $v;
&nbsp;
  foreach (array_keys($_SERVER) as $k) if ($val = strval($_SERVER[$k]) &#038;&#038; !empty($val)) $oa[(substr($k, 0, 5) == &#039;HTTP_&#039; ? &#039;HTTP&#039; : &#039;SERVER&#039;)][$k] = $_SERVER[$k];

  return $oa;
}
</pre>
<h3>get_debug_loaded_extensions</h3>
<p>Returns a list of all the loaded extensions in php.  If verbose it also returns their functions!</p>
<pre>
function get_debug_loaded_extensions($vb=false)
{
  $oa=array();
  foreach((array)@get_loaded_extensions() as $k=&gt;$v) $oa[$v]= ($vb===false) ? &#039;&#039; : (array)@get_extension_funcs($v);
  return $oa;
}
</pre>
<p><a href="http://www.askapache.com/wordpress/debug-viewer-plugin.html">AskApache Debug Viewer Plugin for WordPress</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/debug-viewer-plugin.html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Password Protection Plugin Status</title>
		<link>http://www.askapache.com/htaccess/password-protection-plugin-status.html</link>
		<comments>http://www.askapache.com/htaccess/password-protection-plugin-status.html#comments</comments>
		<pubDate>Sun, 01 Mar 2009 17:39:57 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[.htaccess plugin]]></category>
		<category><![CDATA[askapache]]></category>
		<category><![CDATA[password protection]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=1966</guid>
		<description><![CDATA[<p><a class="IFL" href="/wp-content/uploads/2009/03/apache-security-model-tall1.png"><img src="/wp-content/uploads/2009/03/apache-security-model-tall1-250x123.png" alt="Apache Security Model - In Color" title="apache-security-model-wide" width="250" height="123" /></a>I wanted to address why the update to the AskApache Password Protection plugin didn't happen pre-2009 as I had hoped.. Mostly due to my job but I thought I could at least fill you in.  Oh and this is going to get very boring very fast, unless you're ready to rumble in the zone.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p>I wanted to address why the update to the AskApache Password Protection plugin didn&#8217;t happen pre-2009 as I had hoped.. Mostly due to my job but I thought I could at least fill you in.  Oh and this is going to get very boring very fast, unless you&#8217;re ready to rumble in the zone.</p>
<h2>File Permissions!</h2>
<p>The main issue with the password protection plugin working for some people and not others is due to <a title="detailed file permission article" href="http://www.askapache.com/security/chmod-stat.html">file permission configurations</a>.  WordPress is simply a group of .php files saved on your server.  The actual program that is in fact running WordPress is the <a title="SuEXEC and php.cgi" href="http://www.askapache.com/htaccess/php-cgi-redirect_status.html">PHP interpreter</a>, which is in turn controlled by the Apache Server.  Almost all computers are running at least 2 servers, the Web Server which serves and displays your files, and a FTP server.</p>
<p><a class="IFL" href="/wp-content/uploads/2009/03/apache-security-model-tall1.png"><img src="/wp-content/uploads/2009/03/apache-security-model-tall1-250x123.png" alt="Apache Security Model - In Color" title="apache-security-model-wide" width="250" height="123" /></a>  Here&#8217;s a detailed look at the Apache Security Model, from <a href="http://www.apachesecurity.net/blog/2009/02/apache_security_model.html">ApacheSecurity.net</a>, a blog maintained by <em>Ivan Ristic</em>, the author of <a href="http://www.modsecurity.org/">ModSecurity</a>.<br class="C" /></p>
<p>The problem is happening because when you login to your FTP server with your username and password, the files that you upload are then  owned by that username and password, which is almost always an actual user account on the server system.  But the Apache Server is an executable file itself, and it is not owned by your FTP username, for security reasons.  Apache controls the PHP Interpreter, which parses and executes the WordPress and plugin files as a separate user.  ( <a href="http://httpd.apache.org/docs/trunk/suexec.html">SuEXEC</a>, <a href="http://httpd.apache.org/docs/trunk/misc/security_tips.html">Apache Security Tips</a> ) </p>
<p>So what happens is the <code>askapache-password-protect.php</code> file saved on your server and is owned by the user that created it (if you downloaded it to your computer then used ftp to transfer, your ftp user owns it..  if you used a php downloader script, then the php process owner owns it)   So when you click on the Run Tests button from the WordPress administration website what you are doing is sending a request via HTTP to your Apache Server process, which sees the requested file is .php so it then runs the php interpreter to execute the askapache-password-protect.php file, then that file uses programming to attempt and write/modify a file in your blog&#8217;s root directory.</p>
<h2>Process Owner vs. File Owner</h2>
<p>So who owns your blog&#8217;s root directory?  Your ftp user account/ you do..   but who owns the process that is trying to write/modify a file that is owned by your ftp user?  The PHP Process that is actually executing the file access/write requests.  This is the core way that 99% of all web sites get cracked into.. All these malicious robots and exploit bots do is attempt to write a file onto your server so that it can then be used to take over your site.  If they can save a file on your blog&#8217;s directory (uploads, insecure plugin code, not filtering user input, etc..) it inherits the permissions of the process that actually wrote the data bits onto the hard-drive.</p>
<p>So some server-admins/web hosts configure the php interpreter to not have write access anywhere except for a couple neccessary locations like /tmp.  They have auto-installation&#8217;s available through their online web panels, meaning instead of executing .php scripts in your user directory as the php process they force you to use, they can bypass all that because the installation scripts they use are all on their systems, not on your &#8220;locked-down&#8221; cluster.</p>
<p>This is the fundamental security battle that network server security is all based on..   Apache is owned by a powerful user because it owns the server process, so apache is often run as the user dhapache or nobody..  If a cracker is able to find a way to get a file saved on your server with the dhapache user as the owner then they&#8217;ve basically just gotten control of the whole thing.  When you upload a file to your server using the add attachment form in wordpress, the file first goes through the dhapache user which passes the file to the php process owner which has much less permissions.  Apache has been in open-source development for many many years now, its the safest most secure server in the world, windows servers are hackable, apache servers are hacked usually only when the sysadmin configures it wrong or accidentally.</p>
<p>Believe it or not, as confusing as my feeble explanation was, this is only like .1% of whats going on.. I&#8217;ve basically spent the last several months developing the new version specifically to be able to work no matter what configuration you have.  What I ended up doing was finding ways to bypass this security on a couple hosting providers that are setup in this way, but even though I got it to work in most instances it basically was hacking their systems, and if I published that code to automatically bypass web-hosts security setups I think I&#8217;d be in big trouble and they would just close those specific holes and the plugin would not work again.   So I decided instead of exploiting host-specifics hacks to get the plugin to work that I would focus on the method that WordPress sorta uses.  The code they have now (2.8 bleeding-edge) still isn&#8217;t where it needs to be, but this is some difficult stuff and they have a brilliant start, it&#8217;ll work.. just a question of when.</p>
<h2><code>wp-admin/includes/file.php</code></h2>
<p>Ok so this function <code>get_filesystem_method</code> is a brilliant bit of code that would&#8217;ve been beyond my current PHP skills to come up with.  It determines which if any of the following methods can be used to modify files on your server from within WordPress, which is exactly what the new version of the passpro plugin needs to use.   The first test simply creates a file from within php using wp_tempnam, a function that attempts to locate and write to a temporary location on your server that has the best chance of having write access.  If it is successfully created (this code assumes that it will be, something they need to fix) then the fileowner (uses stat internally) of the temp file just created is compared to the owner of the php script&#8230;  Normally this works and then the plugin woks too, but on some hosts the script is running as a separate user than that of the file which means you can&#8217;t directly access the local file system.  That is what is occurring for most of you who experience permission problems while testing the plugin.  There are thousands of caveats for each little part depending on your php version, php setup, server setup, server version, which Server API you are using, the type of SAPI being used, and on and on..</p>
<pre>
function get_filesystem_method($args = array()) {
  $method = false;
  if( function_exists(&#039;getmyuid&#039;) &#038;&#038; function_exists(&#039;fileowner&#039;) ){
    $temp_file = wp_tempnam();
    if ( getmyuid() == fileowner($temp_file) ) $method = &#039;direct&#039;;
    unlink($temp_file);
  }
  if ( ! $method &#038;&#038; isset($args[&#039;connection_type&#039;]) &#038;&#038; &#039;ssh&#039; == $args[&#039;connection_type&#039;] &#038;&#038; extension_loaded(&#039;ssh2&#039;) )
          $method = &#039;ssh2&#039;;
  if ( ! $method &#038;&#038; extension_loaded(&#039;ftp&#039;) )
          $method = &#039;ftpext&#039;;
  if ( ! $method &#038;&#038; ( extension_loaded(&#039;sockets&#039;) || function_exists(&#039;fsockopen&#039;) ) )
          $method = &#039;ftpsockets&#039;; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
  return apply_filters(&#039;filesystem_method&#039;, $method);
}
</pre>
<h2>Enumerating Permissions can be Annoying</h2>
<p>This was part of some tests I did to see what kind of access I had with the very helpful posix functions which are very accurate as well since they were designed for a system with file permissions, ie. not Win.  Don&#8217;t ask me how because I won&#8217;t tell you, but on one of the hosts I was testing on that did not allow direct access I was able to get the Apache server running as dhapache to erroneously write a file into my users blog directory.  This is a big security no-no and I now have my .htaccess file written into the blog directory where it should go, but instead of my php script&#8217;s user having write access to the file so I can modify it, its owned by dhapache!  Because the file is owned by dhapache I shouldn&#8217;t even be allowed to know it exists, but there it is.  So the next step was to try and take ownership of the .htaccess file so that I could modify it.  I tried and tried but was unsuccessful, I couldn&#8217;t modify it so that was another dead end.  Actually it took me awhile to figure out how to remove the file from my directory.  Being that it was owned by dhapache I couldn&#8217;t delete or modify it using my php process or even through ftp/ssh!  Sysadmins regularly run find commands that search the servers for any files owned by dhapache that should not be there as this is a big red flag that someone has found a way to manipulate dhapache which could potentially lead to modifying dhapche-owned server config files.. Luckily I was able to delete it by basically running the hack again to overwrite the file.</p>
<pre>
  if ((posix_setgid(getmygid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETGID of {$file}  to " . getmygid(), 3);
  elseif ((posix_setgid(filegroup(__file__))) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETUID of {$file} to " . filegroup(__file__), 3);
  if ((posix_setegid(getmygid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETEGID of {$file} to " . getmygid(), 3);
  elseif ((posix_setegid(filegroup(__file__))) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETEGID of {$file} to " . filegroup(__file__), 3);
  if ((posix_setuid(getmyuid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETUID of {$file}  to " . getmyuid(), 3);
  elseif ((posix_setuid(get_current_user())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETUID of {$file} to " . get_current_user(), 3);
  if ((posix_seteuid(getmyuid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETEUID of {$file} to " . getmyuid(), 3);
  elseif ((posix_seteuid(get_current_user())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing SETEUID of {$file} to " . get_current_user(), 3);
  if ((chmod($file, FS_CHMOD_DIR) || chmod($file, 0776) || chmod($file, 0766) || chmod($file,
    FS_CHMOD_FILE)) !== false) $this-&gt;to_log(&#039;&#039;, 1, "Success Changing Mode of {$file}", 3);
  if ((chown($file, getmyuid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Ownership of {$file} to " . getmyuid(), 3);
  elseif ((chown($file, get_current_user())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Ownership of {$file} to " . get_current_user(), 3);
  if ((chgrp($file, getmygid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Group of {$file} to " . getmygid(), 3);
  elseif ((chgrp($file, filegroup(__file__))) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Group of {$file} to " . filegroup(__file__), 3);
  if ((chmod($file, FS_CHMOD_DIR) || chmod($file, 0776) || chmod($file, 0766) || chmod($file,
    FS_CHMOD_FILE)) !== false) $this-&gt;to_log(&#039;&#039;, 1, "Success Changing Mode of {$file}", 3);
  if ((chown($file, getmyuid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Ownership of {$file} to " . getmyuid(), 3);
  elseif ((chown($file, get_current_user())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Ownership of {$file} to " . get_current_user(), 3);
  if ((chgrp($file, getmygid())) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Group of {$file} to " . getmygid(), 3);
  elseif ((chgrp($file, filegroup(__file__))) !== false) $this-&gt;to_log(&#039;&#039;, 1,
      "Success Changing Group of {$file} to " . filegroup(__file__), 3);
  return (!$this-&gt;_fclose($fh)) ? $this-&gt;to_log(__function__ . &#039;:&#039; . __line__ .
    " Error closing {$mode} handle for {$file}", 0) : $total;
</pre>
<p>If php process isn&#8217;t allowed to write to your web directory but you have an ftp account that is, then we request your ftp username/password in wordpress and if the php process running the <code>askapache-password-protect.php</code> plugin script is allowed access to <a href="http://www.askapache.com/php/fsockopen-socket.html">raw networking sockets using fsockopen</a> then we can basically access and write to your blog&#8217;s <code>.htaccess</code> file by using php to mimick an ftp client session. There are also other protocols and options available using php if ftp/fsockopen isn&#8217;t allowed, but you run out of alternatives quick.  Using the curl extension is one option.</p>
<p>So I wrote my own ftp library for a fsockopen class I had already developed for specific test requirements in unreleased versions, so the release of the new askapache password protect plugin will work for 75% or so of the people who have trouble now.. not to mention the insane logging and debugging I&#8217;ve added while looking for the reasons some web-hosts still don&#8217;t work.  Some use custom php security modules, wrappers, and custom virtual servers that are akin to a vmware server.  So for maybe 10% of those running apache who have had problems they would still have them. I&#8217;m still playing with some ssh capability from within the plugin similar to the ftp technique..  I really hope WordPress just adds this functionality by updating their current filesystem classes..</p>
<h2>Fsockopen Payload Class</h2>
<p>Here&#8217;s what I had several versions ago.. Just sticking it up here in case anyone is curious, one cool thing this version starts to incorporate is being able to send direct data payloads across the socket so it can be used like <a href="http://metasploit.com/" title="Metasploit provides useful information to people who perform penetration testing, IDS signature development, and exploit research.">the metasploit framework</a> to send payloads of exploits, but of course we&#8217;re using it to mimick other protocols like ftp, which can be setup by feeding hex into the socket direct from a real ftp client, and piping the output. Keep in mind that this is my first time using php classes, so the learning curve has been incredible&#8230;</p>
<pre>
&lt;?php
error_log("RUNNING " . basename(__file__) . "\n");
if (!in_array(&#039;AskApache_Net&#039;, get_declared_classes()) &#038;&#038; !class_exists(&#039;AskApache_Net&#039;)):
 class AskApache_Net extends AskApachePassPro
 {
  var $_fp = null;
  var $_socket = array(&#039;protocol&#039; =&gt; &#039;1.0&#039;, &#039;method&#039; =&gt; &#039;GET&#039;, &#039;referer&#039; =&gt;
   &#039;http://www.askapache.com/&#039;, &#039;port&#039; =&gt; &#039;80&#039;, &#039;ua&#039; =&gt;
   &#039;Mozilla/5.0 (compatible; AskApache_Net/1.6; http://www.askapache.com/)&#039;, &#039;scheme&#039; =&gt;
   &#039;http&#039;, &#039;transport&#039; =&gt; &#039;&#039;, &#039;host&#039; =&gt; &#039;&#039;, &#039;user&#039; =&gt; &#039;&#039;, &#039;pass&#039; =&gt; &#039;&#039;, &#039;path&#039; =&gt; &#039;/&#039;,
   &#039;query&#039; =&gt; &#039;&#039;, &#039;fragment&#039; =&gt; &#039;&#039;);
  var $authtype = &#039;Basic&#039;;
  var $timeout = 15;
  var $_dh = &#039;&#039;;
  var $_digest = array(&#039;realm&#039; =&gt; &#039;&#039;, &#039;nonce&#039; =&gt; &#039;&#039;, &#039;uri&#039; =&gt; &#039;&#039;, &#039;algorithm&#039; =&gt; &#039;MD5&#039;,
   &#039;qop&#039; =&gt; &#039;auth&#039;, &#039;opaque&#039; =&gt; &#039;&#039;, &#039;domain&#039; =&gt; &#039;&#039;, &#039;nc&#039; =&gt; &#039;00000001&#039;, &#039;cnonce&#039; =&gt;
   &#039;82d057852a9dc497&#039;, &#039;A1&#039; =&gt; &#039;&#039;, &#039;A2&#039; =&gt; &#039;&#039;, &#039;response&#039; =&gt; &#039;&#039;);
  var $_ACLF = "\r\n";
  var $_request_body = &#039;&#039;;
  var $_request_headers = array();
  var $_response_headers = array();
  var $my_headers;
  var $_response_header = &#039;&#039;;
  var $_response_protocol = &#039;&#039;;
  var $_response_version = &#039;&#039;;
  var $_response_code = &#039;&#039;;
  var $_response_message = &#039;&#039;;
  var $_response_body = &#039;&#039;;
  var $_errs = array(3 =&gt; &#039;Socket creation failed&#039;, 4 =&gt; &#039;DNS lookup failure&#039;, 5 =&gt;
   &#039;Connection refused or timed out&#039;, 111 =&gt; &#039;Connection refused&#039;, 113 =&gt;
   &#039;No route to host&#039;, 110 =&gt; &#039;Connection timed out&#039;, 104 =&gt; &#039;Connection reset by client&#039;);

  /**
   * AskApache_Net::AskApache_Net()
   */
  function AskApache_Net()
  {
   return $this-&gt;__construct();
  }

  /**
   * AskApache_Net::__destruct()
   */
  function __destruct()
  {
   $this-&gt;_timer(&#039;class&#039;);
   return true;
  }

  /**
   * AskApache_Net::__construct()
   */
  function __construct()
  {
   $this-&gt;_timer(&#039;class&#039;);
   $this-&gt;_ACLF = chr(13) . chr(10);
   @set_time_limit(60);
   return true;
  }

  /**
   * AskApache_Net::hsockit()
   */
  function hsockit($URI)
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   $this-&gt;_socket[&#039;method&#039;] = &#039;HEAD&#039;;
   return $this-&gt;sockit($URI);
  }

  /**
   * AskApache_Net::sockit()
   */
  function sockit($URI = &#039;&#039;)
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if (!$this-&gt;_build_sock($URI)) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__,
     "Failed!", 0);
   if (!$this-&gt;_connect()) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__, "Failed!", 0);
   $this-&gt;_build_request();
   if (!$this-&gt;_build_request()) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__,
     "Failed!", 0);
   if (!$this-&gt;_tx()) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__, "tx Failed!", 0);
   if (!$this-&gt;_rx()) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__, "rx Failed!", 0);
   if (!$this-&gt;_disconnect()) return $this-&gt;msg(__function__ . &#039;:&#039; . __line__,
     "disconnect Failed!", 0);
   if ((bool)$this-&gt;net_debug === true) {
    foreach (array(&#039;out_payload&#039;, &#039;_request_body&#039;, &#039;_response_header&#039;, &#039;_response_body&#039;) as
     $nam) {
     if (is_array($this-&gt;$nam)) {
      if (sizeof($this-&gt;$nam) &gt; 1) {
       echo "\n\n{$nam}\n";
       print_r($this-&gt;$nam);
      }
     } else {
&nbsp;
      if (!empty($this-&gt;$nam)) {
       echo "\n\n{$nam}\n";
       echo $this-&gt;$nam;
      }
     }
    }
    $this-&gt;tcp_trace(1);
   }
   return (int)$this-&gt;_response_code;
  }

  /**
   * AskApache_Net::_build_sock()
   */
  function _build_sock($url)
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   $socket_info = &#038;$this-&gt;_socket;
   if (!$u_bits = parse_url($url)) return false;
   if (empty($u_bits[&#039;method&#039;])) $u_bits[&#039;method&#039;] = &#039;GET&#039;;
   if (empty($u_bits[&#039;protocol&#039;])) $u_bits[&#039;protocol&#039;] = &#039;1.0&#039;;
   if (empty($u_bits[&#039;host&#039;])) $u_bits[&#039;host&#039;] = $_SERVER[&#039;HTTP_HOST&#039;];
   if (empty($u_bits[&#039;scheme&#039;])) $u_bits[&#039;scheme&#039;] = &#039;http&#039;;
   if (empty($u_bits[&#039;port&#039;])) $u_bits[&#039;port&#039;] = $_SERVER[&#039;SERVER_PORT&#039;];
   $u_bits[&#039;path&#039;] = (empty($u_bits[&#039;path&#039;]) ? &#039;/&#039; : $u_bits[&#039;path&#039;]) . (!empty($u_bits[&#039;query&#039;]) ?
    &#039;?&#039; . $u_bits[&#039;query&#039;] : &#039;&#039;);
   if (empty($u_bits[&#039;ua&#039;])) $u_bits[&#039;ua&#039;] =
     &#039;Mozilla/5.0 (compatible; AskApache_Net/1.0; http://www.askapache.com)&#039;;
   if (empty($u_bits[&#039;referer&#039;])) $u_bits[&#039;referer&#039;] = &#039;http://www.askapache.com&#039;;
   if (empty($u_bits[&#039;fragment&#039;])) unset($u_bits[&#039;fragment&#039;]);
   if (empty($u_bits[&#039;user&#039;])) unset($u_bits[&#039;user&#039;]);
   if (empty($u_bits[&#039;pass&#039;])) unset($u_bits[&#039;pass&#039;]);
   if ($u_bits[&#039;scheme&#039;] == &#039;https&#039; || $this-&gt;_socket[&#039;scheme&#039;] == &#039;https&#039;) $u_bits[&#039;transport&#039;] =
     &#039;ssl://&#039;;
   if ($u_bits[&#039;scheme&#039;] == &#039;https&#039; || $this-&gt;_socket[&#039;scheme&#039;] == &#039;https&#039;) $u_bits[&#039;port&#039;] =
     &#039;443&#039;;
   $socket_info = $this-&gt;_parse_args($u_bits, $socket_info);
   extract($socket_info, EXTR_SKIP);
   return true;
  }

  /**
   * AskApache_Net::_build_auth_header()
   */
  function _build_auth_header()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if ($this-&gt;authtype == &#039;Basic&#039;) $this-&gt;_request_headers[] = &#039;Authorization: Basic &#039; .
     base64_encode($this-&gt;_socket[&#039;user&#039;] . ":" . $this-&gt;_socket[&#039;pass&#039;]);
   elseif ($this-&gt;authtype == &#039;Digest&#039;) {
    $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
    $this-&gt;_socket[&#039;protocol&#039;] = &#039;1.1&#039;;
    $hdr = $mtx = array();
    preg_match_all(&#039;/(\w+)=(?:"([^"]+)"|([^\s,]+))/&#039;, $this-&gt;_dh, $mtx, PREG_SET_ORDER);
    foreach ($mtx as $m) $hdr[$m[1]] = $m[2] ? $m[2] : $m[3];
    foreach ($hdr as $key =&gt; $val)
     if (array_key_exists($key, $this-&gt;_digest) &#038;&#038; !empty($val)) $this-&gt;_digest[$key] = $val;
    $this-&gt;_digest[&#039;uri&#039;] = $this-&gt;_socket[&#039;path&#039;];
    $this-&gt;_digest[&#039;A1&#039;] = md5($this-&gt;_socket[&#039;user&#039;] . &#039;:&#039; . $this-&gt;_digest[&#039;realm&#039;] .
     &#039;:&#039; . $this-&gt;_socket[&#039;pass&#039;]);
    $this-&gt;_digest[&#039;A2&#039;] = md5($this-&gt;_socket[&#039;method&#039;] . &#039;:&#039; . $this-&gt;_socket[&#039;path&#039;]);
    $this-&gt;_digest[&#039;response&#039;] = md5($this-&gt;_digest[&#039;A1&#039;] . &#039;:&#039; . $this-&gt;_digest[&#039;nonce&#039;] .
     &#039;:&#039; . $this-&gt;_digest[&#039;nc&#039;] . &#039;:&#039; . $this-&gt;_digest[&#039;cnonce&#039;] . &#039;:&#039; . $this-&gt;_digest[&#039;qop&#039;] .
     &#039;:&#039; . $this-&gt;_digest[&#039;A2&#039;]);
    $this-&gt;_request_headers[] = sprintf(&#039;Authorization: Digest username="%1$s", realm="%2$s", nonce="%3$s",&#039;.
     &#039;uri="%4$s", algorithm=%5$s, response="%6$s", qop="%7$s", nc="%8$s"%9$s%10$s&#039;,
     $this-&gt;_socket[&#039;user&#039;], $this-&gt;_digest[&#039;realm&#039;], $this-&gt;_digest[&#039;nonce&#039;], $this-&gt;
     _digest[&#039;uri&#039;], $this-&gt;_digest[&#039;algorithm&#039;], $this-&gt;_digest[&#039;response&#039;], $this-&gt;
     _digest[&#039;qop&#039;], $this-&gt;_digest[&#039;nc&#039;], !empty($this-&gt;_digest[&#039;cnonce&#039;]) ? &#039;, cnonce="&#039; .
     $this-&gt;_digest[&#039;cnonce&#039;] . &#039;"&#039; : &#039;&#039;, !empty($this-&gt;_digest[&#039;opaque&#039;]) ? &#039;, opaque="&#039; .
     $this-&gt;_digest[&#039;opaque&#039;] . &#039;"&#039; : &#039;&#039;);
   }
   return true;
  }

  /**
   * AskApache_Net::_build_request()
   */
  function _build_request()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   $this-&gt;_request_headers[] = $this-&gt;_socket[&#039;method&#039;] . " " . $this-&gt;_socket[&#039;path&#039;] .
    " HTTP/" . $this-&gt;_socket[&#039;protocol&#039;];
   if (is_array($this-&gt;my_headers) &#038;&#038; sizeof($this-&gt;my_headers) &gt; 0) $this-&gt;
     _request_headers = array_merge($this-&gt;_request_headers, $this-&gt;my_headers);
   else {
    $this-&gt;_request_headers[] = "Host: " . $this-&gt;_socket[&#039;host&#039;];
    $this-&gt;_request_headers[] = "User-Agent: " . $this-&gt;_socket[&#039;ua&#039;];
    $this-&gt;_request_headers[] = &#039;Accept: application/xhtml+xml,text/html;q=0.9,*/*;q=0.5&#039;;
    $this-&gt;_request_headers[] = &#039;Accept-Language: en-us,en;q=0.5&#039;;
    $this-&gt;_request_headers[] = &#039;Accept-Encoding: none&#039;;
    $this-&gt;_request_headers[] = &#039;Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7&#039;;
    $this-&gt;_request_headers[] = &#039;Referer: &#039; . $this-&gt;_socket[&#039;referer&#039;];
   }
   if (!empty($this-&gt;_socket[&#039;user&#039;]) &#038;&#038; !empty($this-&gt;_socket[&#039;pass&#039;])) $this-&gt;
     _build_auth_header();
   if ($this-&gt;out_payload !== false) $this-&gt;_request_body = $this-&gt;out_payload;
   else  $this-&gt;_request_body = join($this-&gt;_ACLF, $this-&gt;_request_headers) . $this-&gt;
     _ACLF . $this-&gt;_ACLF;
   return true;
  }

  /**
   * AskApache_Net::_tx()
   */
  function _tx()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   return (bool)(is_resource($this-&gt;_fp) &#038;&#038; $this-&gt;_netwrite($this-&gt;_fp, $this-&gt;
    _request_body));
  }

  /**
   * AskApache_Net::_rx()
   */
  function _rx()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if (!is_resource($this-&gt;_fp)) return false;
   $this-&gt;_response = $this-&gt;_netread($this-&gt;_fp, 500000);
   $parts = explode($this-&gt;_ACLF . $this-&gt;_ACLF, ltrim($this-&gt;_response), 2);
   $this-&gt;_response_header = trim($parts[0]);
   $this-&gt;_response_body = trim($parts[1]);
   if (preg_match(&#039;#([^/]*)/([\d\.]+) ([\d]*?) (.*)#&#039;, $this-&gt;_response_header, $htx)) {
    $this-&gt;_response_protocol = trim($htx[1]);
    $this-&gt;_response_version = trim($htx[2]);
    $this-&gt;_response_code = trim($htx[3]);
    $this-&gt;_response_message = trim($htx[4]);
   }
   if (preg_match_all(&#039;#([^:]+)\:?(.*)#&#039;, str_replace($htx, &#039;&#039;, $this-&gt;_response_header),
    $mtx, PREG_SET_ORDER)) {
    foreach ($mtx as $m) {
     $this-&gt;_headers[strtolower(trim($m[1]))] = trim($m[2]);
     if (preg_match(&#039;/(WWW|Proxy)-Authenticate:.*Digest/i&#039;, trim($m[1]))) $this-&gt;_dh =
       trim($m[1]);
    }
   }
   return true;
  }

  /**
   * AskApache_Net::tcp_trace()
   */
  function tcp_trace($p = false)
  {
   $this-&gt;_timer(__function__ );
   $ret = join("\n", array_merge((array )$this-&gt;_request_headers, array(&#039;&#039;), (array )$this-&gt;
    _response_headers));
   if ($p !== false) {
    echo $ret;
    $ret = true;
   }
   $this-&gt;_timer(__function__ );
   return $ret;
  }

  /**
   * AskApache_Net::_get_ip()
   */
  function _get_ip($host)
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
&nbsp;
   if (!preg_match(&#039;/^[\t ]*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[\t ]*$/&#039;, $host)) $hostip =
     gethostbyname($host);
   $ip = ($hostip == $host) ? $host : long2ip(ip2long($hostip));
   return $ip;
  }

  /**
   * AskApache_Net::_connect()
   */
  function _connect()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if (false === ($this-&gt;_fp = fsockopen($this-&gt;_get_ip($this-&gt;_socket[&#039;host&#039;]), $this-&gt;
    _socket[&#039;port&#039;], $errno, $errstr, $this-&gt;timeout)) || !is_resource($this-&gt;_fp)) {
    $err = (array_key_exists($errno, $this-&gt;_errs)) ? $this-&gt;_errs[$errno] :
     &#039;Connection failed&#039;;
    return $this-&gt;msg(__function__ . &#039;:&#039; . __line__ . " Fsockopen failed! [{$errno}] {$err} ({$errstr})",
     0);
   }
   if (function_exists("socket_set_timeout")) socket_set_timeout($this-&gt;_fp, $this-&gt;
     timeout);
   elseif (function_exists("stream_set_timeout")) stream_set_timeout($this-&gt;_fp, $this-&gt;
     timeout);
   usleep(10000);
   return true;
  }

  /**
   * AskApache_Net::_disconnect()
   */
  function _disconnect()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if (is_resource($this-&gt;_fp)) return $this-&gt;_fclose($this-&gt;_fp);
   else  $this-&gt;_fp = null;
   return true;
  }

  /**
   * AskApache_Net::get_response_headers()
   */
  function get_response_headers($header = false)
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   if ($header !== false &#038;&#038; array_key_exists($header, $this-&gt;_response_headers)) return $this-&gt;
     _response_headers[$header];
   return $this-&gt;_response_headers;
  }

  /**
   * AskApache_Net::get_response_body()
   */
  function get_response_body()
  {
   $this-&gt;msg(__function__ . &#039;:&#039; . __line__, 3);
   return $this-&gt;_response_body;
  }

  /**
   * AskApache_Net::_netread()
   */
  function _netread(&#038;$fh, $ts = 50000000, $bs = 124)
  {
   $this-&gt;_timer(__function__ );
   for ($d = $b = &#039;&#039;, $rt = $at = $r = 0; ($fh !== false &#038;&#038; !feof($fh) &#038;&#038; $b !== false &#038;&#038;
    $at &lt; 50000000 &#038;&#038; $rt &lt; $ts); $r = $ts - $rt, $bs = (($bs &gt; $r) ? $r : $bs), $this-&gt;
    _timer("R: {$rt}"), $b = fread($fh, $bs), $br = strlen($b), $d .= $b, $this-&gt;_timer("R: {$rt}"),
    $rt += $br, $at++, $this-&gt;msg("[RT: {$rt}]\t[BR: {$br}" . (($ts != 50000000) ? "]\t\t [{$r} / {$ts}]" :
    " : {$bs}]\t[{$at}]"))) ;
   $this-&gt;_timer(__function__ );
   return ((strlen($d) != 0)) ? $d : false;
  }

  /**
   * AskApache_Net::_netwrite()
   */
  function _netwrite(&#038;$fh, $d = &#039;&#039;, $bs = 512)
  {
   $this-&gt;_timer(__function__ );
&nbsp;
   for ($bw = $wt = $at = 0, $dat = &#039;&#039;, $ts = strlen($d); ($fh !== false &#038;&#038; $bw !== false &#038;&#038;
    $at &lt; 50000000 &#038;&#038; $wt &lt; $ts); $r = $ts - $wt, $bs = (($bs &gt; $r) ? $r : $bs), $dat =
    substr($d, $wt, $bs), $bw = fwrite($fh, $dat), $wt += $bw, $this-&gt;msg("[WT: {$wt}]\t[BW: {$bw}]\t\t[I: {$r} / {$ts}:{$bs}] - {$at}"),
    $at++) ;
   $this-&gt;msg("[WT: {$wt}]\t[BW: {$bw}]\t\t[I: {$r} / {$ts}:{$bs}] - {$at}");
   $this-&gt;_timer(__function__ );
   return ($wt == $ts) ? true : false;
  }
 }
endif;
?&gt;
</pre>
<p>So I decided to finally give in to what I&#8217;ve been avoiding all along and added a php-software-based method that will work on everycomputer, windows, blackberrys, etc.. That took me about 15minutes as its just a few lines of code.. The problem I have with it is that php is what is actually controlling the sending, receiving, and verifying of the authentication headers instead of using the builtin super-secure apache method.</p>
<p>Here&#8217;s how you would block someone using the apache/askapache way:</p>
<pre>
[Exploit Request] =&gt; ([BLOCKED]-AskApache)
</pre>
<p>This prevents the exploit from even reaching PHP, saving your computer a lot of CPU/memory and bandwdith, and obviously can&#8217;t exploit wordpress if php isn&#8217;t even loading.</p>
<p>Here&#8217;s how the php-software-based method blocks the same request:</p>
<pre>
[Exploit Request] =&gt; (AskApache) =&gt; (PHP) =&gt; (WordPress) =&gt; ([BLOCKED]-askapache-password-protect.php)
</pre>
<p>So the last bit of programming and research I&#8217;m doing at the moment is how to cause the askapache-password-protect plugin to execute as soon as possible, ideally it would execute before WordPress starts..   And I am still crazy swamped at work, this was the longest non-posting period of the blog to date!</p>
<p><a href="http://www.askapache.com/htaccess/password-protection-plugin-status.html">Password Protection Plugin Status</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/htaccess/password-protection-plugin-status.html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>.htaccess Plugin Blocks Spam, Hackers, and Password Protects Blog</title>
		<link>http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html</link>
		<comments>http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html#comments</comments>
		<pubDate>Sat, 22 Nov 2008 14:18:12 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[htaccess rewrites]]></category>
		<category><![CDATA[mod_rewrite]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=1053</guid>
		<description><![CDATA[<p><a class="IFL" href="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html"><img src="/wp-content/uploads/2008/11/htaccess-plugin-2.png" alt=".htaccess security plugin 2" title=".htaccess security plugin 2" /></a><br /><br />Well what can I say, <strong>other than this is sooo DOPE</strong>!  Here is a list of the modules this plugin (version 4.7 unreleased) will automatically detect.  I compiled the list myself using every module included with any default Apache installation for ALL the versions listed below, 1.3 to 2.2+<br /><br />Want to know something else I'm including in this plugin?  For each and every module that is detected, this plugin can then detect ALL of the modules .htaccess Directives!  For instance, <code>RewriteRule, AccessFileName, AddHandler, etc..</code> are each a directive belonging to a module that is allowed to be used from within .htaccess files.<br /><br /><strong>Talk about sick.. these tricks have the diamond disease!</strong><br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a class="IFL" href="/wp-content/uploads/2008/11/htaccess-plugin-2.png"><img src="/wp-content/uploads/2008/11/htaccess-plugin-2.png" alt=".htaccess security plugin 2" title=".htaccess security plugin 2" /></a></p>
<p>Well what can I say, <strong>other than this is sooo DOPE</strong>!  Here is a <a href="#htaccess-module-list">list of the modules</a> this plugin (version 4.7 unreleased) will automatically detect.  I compiled the list myself using every module included with any default Apache installation for ALL the versions listed below, 1.3 to 2.2+</p>
<p>Want to know something else I&#8217;m including in this plugin?  For each and every module that is detected, this plugin can then detect ALL of the modules .htaccess Directives!  For instance, <code>RewriteRule, AccessFileName, AddHandler, etc..</code> are each a directive belonging to a module that is allowed to be used from within .htaccess files.</p>
<p><strong>Talk about sick.. these tricks have the diamond disease!</strong><br class="C" /></p>
<h2>Screenshot Unreleased 4.7</h2>
<p>I&#8217;ve been making a lot of progress as these screenshots illustrate, including the ability to detect 100% accurately the modules that are enabled on your server.  Big deal!  you might say&#8230; &#8220;How does knowing the modules help?&#8221;</p>
<p>Well it just so happens that in addition to detecting which modules are loaded on your server, this plugin will also detect which Directives are enabled for each module that are allowed to be used from within your .htaccess file!  Future release will provide the ability to explore the different .htaccess directives allowed by your server, so you can do all sorts of cool Apache .htaccess tricks to secure your blog and make it run better.</p>
<p><a href="/wp-content/uploads/2008/11/htaccess-plugin-1.png"><img src="/wp-content/uploads/2008/11/htaccess-plugin-1.png" alt=".htaccess security plugin 1" title=".htaccess security plugin 1" /></a><br /><a href="/wp-content/uploads/2008/11/htaccess-plugin-3.png"><img src="/wp-content/uploads/2008/11/htaccess-plugin-3.png" alt=".htaccess security plugin 3" title=".htaccess security plugin 3" /></a><br /><a href="/wp-content/uploads/2008/11/htaccess-plugin-4.png"><img src="/wp-content/uploads/2008/11/htaccess-plugin-4.png" alt=".htaccess security plugin 4" title=".htaccess security plugin 4" /></a></p>
<h2><a id="htaccess-module-list">Apache Module Detection</a></h2>
<p>Future releases of this plugin will also let you search for non-default modules, wild, beta, and others.</p>
<ul>
<li>mod_access</li>
<li>mod_actions</li>
<li>mod_alias</li>
<li>mod_asis</li>
<li>mod_auth</li>
<li>mod_auth_anon</li>
<li>mod_auth_basic</li>
<li>mod_auth_dbm</li>
<li>mod_auth_digest</li>
<li>mod_auth_ldap</li>
<li>mod_authn_alias</li>
<li>mod_authn_anon</li>
<li>mod_authn_dbd</li>
<li>mod_authn_dbm</li>
<li>mod_authn_default</li>
<li>mod_authn_file</li>
<li>mod_authnz_ldap</li>
<li>mod_authz_dbm</li>
<li>mod_authz_default</li>
<li>mod_authz_groupfile</li>
<li>mod_authz_host</li>
<li>mod_authz_owner</li>
<li>mod_authz_user</li>
<li>mod_autoindex</li>
<li>mod_bucketeer</li>
<li>mod_cache</li>
<li>mod_case_filter</li>
<li>mod_case_filter_in</li>
<li>mod_cern_meta</li>
<li>mod_cgi</li>
<li>mod_cgid</li>
<li>mod_charset_lite</li>
<li>mod_dav</li>
<li>mod_dav_fs</li>
<li>mod_dav_lock</li>
<li>mod_dbd</li>
<li>mod_deflate</li>
<li>mod_dir</li>
<li>mod_disk_cache</li>
<li>mod_dumpio</li>
<li>mod_echo</li>
<li>mod_env</li>
<li>mod_example</li>
<li>mod_expires</li>
<li>mod_ext_filter</li>
<li>mod_file_cache</li>
<li>mod_filter</li>
<li>mod_headers</li>
<li>mod_ident</li>
<li>mod_imagemap</li>
<li>mod_imap</li>
<li>mod_include</li>
<li>mod_info</li>
<li>mod_isapi</li>
<li>mod_log_config</li>
<li>mod_log_forensic</li>
<li>mod_logio</li>
<li>mod_mem_cache</li>
<li>mod_mime</li>
<li>mod_mime_magic</li>
<li>mod_mycore</li>
<li>mod_negotiation</li>
<li>mod_netware</li>
<li>mod_nw_ssl</li>
<li>mod_optional_fn_export</li>
<li>mod_optional_fn_import</li>
<li>mod_optional_hook_export</li>
<li>mod_optional_hook_import</li>
<li>mod_proxy</li>
<li>mod_proxy_ajp</li>
<li>mod_proxy_balancer</li>
<li>mod_proxy_connect</li>
<li>mod_proxy_ftp</li>
<li>mod_proxy_http</li>
<li>mod_rewrite</li>
<li>mod_security</li>
<li>mod_setenvif</li>
<li>mod_so</li>
<li>mod_speling</li>
<li>mod_ssl</li>
<li>mod_status</li>
<li>mod_substitute</li>
<li>mod_suexec</li>
<li>mod_test</li>
<li>mod_unique_id</li>
<li>mod_userdir</li>
<li>mod_usertrack</li>
<li>mod_version</li>
<li>mod_vhost_alias</li>
<li>mod_win32</li>
</ul>
<p><a rel="lb" class="IFL hs hs35" href='/wp-content/uploads/2008/07/http-security-askapache.png' title="http-security-askapache"></a>The original plugin page and description <a href="http://www.askapache.com/wordpress/htaccess-password-protect.html">can be found here</a>.<br class="C" /></p>
<h2>UPDATE: 11/22/08</h2>
<p><a rel="lb" class="IFL hs hs35" href='/wp-content/uploads/2008/07/http-security-askapache.png' title="http-security-askapache"></a><strong>To make a long story short,</strong> I downloaded each major release of the apache httpd source code from version 1.3.0 to version 2.2.10, then I configured and compiled each for a custom HTTPD installation built from source.  This allowed me to find every directive allowed in .htaccess files for each particular version.  <strong style="font-weight:bold;">YES!</strong><br class="C" /></p>
<blockquote cite="http://wordpress.org/support/topic/214390"><p><cite><a href="http://wordpress.org/support/rss/topic/214390">http://wordpress.org/support/rss/topic/214390</a></cite><br />
I&#8217;ve been working on a completely improved version on/off for about a month with the specific goal of finally ending all the little errors that can crop up when dealing with .htaccess.</p>
<p>To that effect I am succeeding marvelously, first I&#8217;ve converted the plugin to a class (4+5 compat), I&#8217;ve replaced my error_handling with WordPress&#8217;s WP_Error class, and the coolest change is the new tests I&#8217;ve added.</p>
<p>To make a long story short, I downloaded each major release of the apache httpd source code starting at version 1.3.0 and finishing with version 2.2.10, I then compiled each version and built a HTTPD from source for all the apache versions.  </p>
<p><em><code>1.3.0</code>, <code>1.3.1</code>, <code>1.3.11</code>, <code>1.3.12</code>, <code>1.3.14</code>, <code>1.3.17</code>, <code>1.3.19</code>, <code>1.3.2</code>, <code>1.3.20</code>, <code>1.3.22</code>, <code>1.3.23</code>, <code>1.3.24</code>, <code>1.3.27</code>, <code>1.3.28</code>, <code>1.3.29</code>, <code>1.3.3</code>, <code>1.3.31</code>, <code>1.3.32</code>, <code>1.3.33</code>, <code>1.3.34</code>, <code>1.3.35</code>, <code>1.3.36</code>, <code>1.3.37</code>, <code>1.3.39</code>, <code>1.3.4</code>, <code>1.3.41</code>, <code>1.3.6</code>, <code>1.3.9</code>, <code>2.0.35</code>, <code>2.0.36</code>, <code>2.0.39</code>, <code>2.0.40</code>, <code>2.0.42</code>, <code>2.0.43</code>, <code>2.0.44</code>, <code>2.0.45</code>, <code>2.0.46</code>, <code>2.0.47</code>, <code>2.0.48</code>, <code>2.0.49</code>, <code>2.0.50</code>, <code>2.0.51</code>, <code>2.0.52</code>, <code>2.0.53</code>, <code>2.0.54</code>, <code>2.0.55</code>, <code>2.0.58</code>, <code>2.0.59</code>, <code>2.0.61</code>, <code>2.0.63</code>, <code>2.1.3-beta</code>, <code>2.1.6-alpha</code>, <code>2.1.7-beta</code>, <code>2.1.8-beta</code>, <code>2.1.9-beta</code>, <code>2.2.0</code>, <code>2.2.10</code>, <code>2.2.2</code>, <code>2.2.3</code>, <code>2.2.4</code>, <code>2.2.6</code>, <code>2.2.8</code>, <code>2.2.9</code></em></p>
<p>Then I went through each version and determined the compatible modules for that version, and I&#8217;m pretty confident that I was also able to find each and every directive allowed by the compatible modules for that version (including core directives).  See <a href="http://www.askapache.com/htaccess/htaccess.html#htaccess-directives">.htaccess directive list</a>.</p>
<p>Basically I can now test a server using a variety of methods and determine almost 100% accurately what version of Apache (down to the API) is running, what modules (and versions) are enabled, and each and every directive that is allowed or disallowed for that version.</p>
<p>So this is so awesome because now we can enable all sorts of additional security features.</p>
<p>Other big changes are:</p>
<ul>
<li>Completely hands-off updates, so that updating the plugin keeps all your settings.</li>
<li>making each SID module have its own configuration and options (like protecting individual files, individual request, and custom exploit strings).</li>
<li>Advanced ErrorDocument usage and handling (like tracking repeat offenders and suggesting they be blocked, emailing admin with custom info, etc..)</li>
<li>Multi User/Group password Control</li>
</ul>
<p>And this time I am developing the plugin using a plethora of wordpress installations and configurations, to make sure that it will work regardless of a custom siteurl, blogid, etc..</p>
<p><strong>Release will come before 2009.. I have some vacations to take and business to finish first. </strong>
</p></blockquote>
<h2>.htaccess Security Modules</h2>
<h3><a id="htaccess-sid700" title="Directory Protection">Directory Protection</a></h3>
<p>Enable the DirectoryIndex Protection, preventing directory index listings and defaulting. [<a href="http://www.askapache.com/htaccess/htaccess.html">Disable</a>]</p>
<pre class='brushhtaccess'>
Options -Indexes
DirectoryIndex index.html index.php /index.php
</pre>
<h3><a id="htaccess-sid800" title="Password Protect wp-login.php">Password Protect wp-login.php</a></h3>
<p>Requires a valid user/pass to access the login page <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-401">401</a>]</p>
<pre class='brushhtaccess'>
&lt;Files wp-login.php&gt;
Order Deny,Allow
Deny from All
Satisfy Any
&nbsp;
AuthName "Protected By AskApache"
AuthUserFile /home/askapache.com/.htpasswda1
AuthType Basic
Require valid-user
&lt;/Files&gt;
</pre>
<h3><a id="htaccess-sid900" title="Password Protect wp-admin">Password Protect wp-admin</a></h3>
<p>Requires a valid user/pass to access any non-static (css, js, images) file in this directory. <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-401">401</a>]</p>
<pre class='brushhtaccess'>
Options -ExecCGI -Indexes +FollowSymLinks -Includes
DirectoryIndex index.php /index.php
&nbsp;
Order Deny,Allow
&nbsp;
Deny from All
Satisfy Any
&nbsp;
AuthName "Protected By AskApache"
AuthUserFile /home/askapache.com/.htpasswda1
AuthType Basic
Require valid-user
&nbsp;
&lt;FilesMatch "\.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$"&gt;
Allow from All
&lt;/FilesMatch&gt;
&nbsp;
&lt;FilesMatch "(async-upload)\.php$"&gt;
&lt;IfModule mod_security.c&gt;
SecFilterEngine Off
&lt;/IfModule&gt;
Allow from All
&lt;/FilesMatch&gt;
</pre>
<h3><a id="htaccess-sid1000" title="Protect wp-content">Protect wp-content</a></h3>
<p>Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-401">401</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-content/.*$ [NC]
RewriteCond %{REQUEST_FILENAME} !^.+flexible-upload-wp25js.php$
RewriteCond %{REQUEST_FILENAME} ^.+\.(php|html|htm|txt)$
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1010" title="Protect wp-includes">Protect wp-includes</a></h3>
<p>Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-includes/.*$ [NC]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ /wp-includes/js/.+/.+\ HTTP/ [NC]
RewriteCond %{REQUEST_FILENAME} ^.+\.php$
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1011" title="Common Exploits">Common Exploits</a></h3>
<p>Block common exploit requests with 403 Forbidden. These can help alot, may break some plugins. [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ ///.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\=?(http|ftp|ssl|https):/.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\?.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(asp|ini|dll).*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(htpasswd|htaccess|aahtpasswd).*\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1012" title="Stop Hotlinking">Stop Hotlinking</a></h3>
<p>Denies any request for static files (images, css, etc) if referrer is not local site or empty. [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{HTTP_REFERER} !^http://www.askapache.com.*$ [NC]
RewriteRule \.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$ - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1015" title="Safe Request Methods">Safe Request Methods</a></h3>
<p>Denies any request not using <a href="http://www.askapache.com/online-tools/request-method-scanner/">GET,PROPFIND,POST,OPTIONS,PUT,HEAD</a> <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|PROPFIND|OPTIONS|PUT)$ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1017" title="Forbid Proxies">Forbid Proxies</a></h3>
<p>Denies any POST Request using a Proxy Server. Can still access site, but not comment.  See <a href="http://perishablepress.com/press/2008/04/20/how-to-block-proxy-servers-via-htaccess/">Perishable Press</a> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:VIA}%{HTTP:FORWARDED}%{HTTP:USERAGENT_VIA}%{HTTP:X_FORWARDED_FOR}%{HTTP:PROXY_CONNECTION} !^$ [OR]
RewriteCond %{HTTP:XPROXY_CONNECTION}%{HTTP:HTTP_PC_REMOTE_ADDR}%{HTTP:HTTP_CLIENT_IP} !^$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1018" title="Real wp-comments-post.php">Real wp-comments-post.php</a></h3>
<p>Denies any POST attempt made to a non-existing wp-comments-post.php <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1019" title="HTTP PROTOCOL">HTTP PROTOCOL</a></h3>
<p>Denies any badly formed HTTP PROTOCOL in the request, 0.9, 1.0, and 1.1 only  <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1020" title="SPECIFY CHARACTERS">SPECIFY CHARACTERS</a></h3>
<p>Denies any request for a url containing characters other than &#8220;a-zA-Z0-9.+/-?=&#038;&#8221;  &#8211; REALLY helps but may break your site depending on your links. [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [a-zA-Z0-9\.\+_/\-\?\=\&#038;]+\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1021" title="BAD Content Length">BAD Content Length</a></h3>
<p>Denies any POST request that doesnt have a Content-Length Header <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Length} ^$
RewriteCond %{REQUEST_URI} !^/(wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1022" title="BAD Content Type">BAD Content Type</a></h3>
<p>Denies any POST request with a content type other than application/x-www-form-urlencoded|multipart/form-data <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Type} !^(application/x-www-form-urlencoded|multipart/form-data.*(boundary.*)?)$ [NC]
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1023" title="Directory Traversal">Directory Traversal</a></h3>
<p>Denies Requests containing ../ or ./. which is a directory traversal exploit attempt <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<h3><a id="htaccess-sid1024" title="PHPSESSID Cookie">PHPSESSID Cookie</a></h3>
<p>Only blocks when a PHPSESSID cookie is sent by the user and it contains characters other than 0-9a-z <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<h3><a id="htaccess-sid1025" title="NO HOST:">NO HOST:</a></h3>
<p>Denies requests that dont contain a HTTP HOST Header. <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{HTTP_HOST} ^$
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1026" title="Bogus Graphics Exploit">Bogus Graphics Exploit</a></h3>
<p>Denies obvious exploit using bogus graphics  <strong>- *** Safe, Use</strong> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{HTTP:Content-Disposition} \.php [NC]
RewriteCond %{HTTP:Content-Type} image/.+ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1027" title="No UserAgent, No Post">No UserAgent, No Post</a></h3>
<p>Denies POST requests by blank user-agents.  May prevent a small number of visitors from POSTING. [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1028" title="No Referer, No Comment">No Referer, No Comment</a></h3>
<p>Denies any comment attempt with a blank HTTP_REFERER field, highly indicative of spam.  May prevent some visitors from POSTING. [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC]
RewriteCond %{HTTP_REFERER} ^-?$
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1029" title="Trackback Spam">Trackback Spam</a></h3>
<p>Denies obvious trackback spam.   See <a href="http://ocaoimh.ie/2008/07/03/more-ways-to-stop-spammers-and-unwanted-traffic/">Holy Shmoly!</a> [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-403">403</a>]</p>
<pre class='brushhtaccess'>
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP_USER_AGENT} ^.*(opera|mozilla|firefox|msie|safari).*$ [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.+/trackback/?\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]
</pre>
<h3><a id="htaccess-sid1030" title="SSL-Only Site">SSL-Only Site</a></h3>
<p>Redirects all non-SSL (https) requests to your https-enabled url [<a href="http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html#status-301">301</a>]</p>
<h3><a id="htaccess-sid2000" title="Anti-Spam, Anti-Exploits">Anti-Spam, Anti-Exploits</a></h3>
<p>Denies Obvious Spam and uses advanced mod_security protection [<a href="http://www.askapache.com/htaccess/mod_security-htaccess-tricks.html">Read More</a>]</p>
<h2>.htaccess Security Module Screenshot</h2>
<p><a rel="lb" href='/wp-content/uploads/2008/07/http-security-askapache.png'><img src="/wp-content/uploads/2008/07/http-security-askapache1.png" alt="" title="http-security-askapache1" /></a></p>
<p><a href="http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html">.htaccess Plugin Blocks Spam, Hackers, and Password Protects Blog</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/htaccess/htaccess-plugin-blocks-spam-hackers-and-password-protects-blog.html/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>New Version of Password Protection Plugin</title>
		<link>http://www.askapache.com/wordpress/new-version-of-password-protection-plugin.html</link>
		<comments>http://www.askapache.com/wordpress/new-version-of-password-protection-plugin.html#comments</comments>
		<pubDate>Tue, 19 Aug 2008 13:08:39 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=1084</guid>
		<description><![CDATA[<p><a class="IFL hs hs23" href="http://www.askapache.com/wordpress/new-version-of-password-protection-plugin.html" title="New AskApache Password Protect Screenshot"></a>4.6 just released.... <a href="http://wordpress.org/extend/plugins/askapache-password-protect/screenshots/">Check It Out.</a><br /><br /><strong style="font-size:19px; text-align:center;">:p</strong><br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p>I added file revisioning support to .htaccess files, so that every time you update or change the .htaccess files it saves the old copy.  The next release will provide a DIFF view of the differences.  <strong>Version 4.7 Almost Done</strong></p>
<p class="anote">You can view the <a href="http://www.askapache.com/htaccess/htaccess-security-block-spam-hackers.html">plugins home page</a>, or <a href="http://wordpress.org/extend/plugins/askapache-password-protect/">view it on the wordpress.org site</a>.</p>
<p>Also fixed all the bugs I was notified about or found, and provided the option to bypass some of the testing if you know your server supports something.</p>
<p>I have to get back to my real job now :)  but for the next release I&#8217;m going to add a whole user-management area to add and remove users and groups from .htpasswd files. </p>
<p>Then it will be ready to start using the advanced SID&#8217;s like mod_security.. </p>
<h2>ScreenShots</h2>
<p><a class="tb" href="/wp-content/uploads/2008/08/screenshot-1.png"><br />
<img src="/wp-content/uploads/2008/08/screenshot-1.png" alt="" /><br />
</a></p>
<p><a href="/wp-content/uploads/2008/08/screenshot-2.png"><br />
<img class="tb" src="/wp-content/uploads/2008/08/screenshot-2.png" alt="" /><br />
</a></p>
<p><a rel="tb" href="/wp-content/uploads/2008/08/screenshot-3.png"><br />
<img src="/wp-content/uploads/2008/08/screenshot-3.png" alt="" /><br />
</a></p>
<p><a href="/wp-content/uploads/2008/08/screenshot-4.png"><br />
<img src="/wp-content/uploads/2008/08/screenshot-4.png" alt="" /><br />
</a></p>
<p><a href="/wp-content/uploads/2008/08/screenshot-5.png"><br />
<img src="/wp-content/uploads/2008/08/screenshot-5.png" alt="" /><br />
</a></p>
<p><a href="/wp-content/uploads/2008/08/screenshot-6.png"><br />
<img src="/wp-content/uploads/2008/08/screenshot-6.png" alt="" /><br />
</a></p>
<p style="font-size:19px;"><strong>:p</strong></p>
<p><a href="http://www.askapache.com/wordpress/new-version-of-password-protection-plugin.html">New Version of Password Protection Plugin</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/new-version-of-password-protection-plugin.html/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>SEO Boost from Google 404 Plugin</title>
		<link>http://www.askapache.com/ajax/404-google-wordpress-plugin.html</link>
		<comments>http://www.askapache.com/ajax/404-google-wordpress-plugin.html#comments</comments>
		<pubDate>Tue, 01 Jul 2008 15:11:16 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Making Money]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Webmaster]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>

		<guid isPermaLink="false">http://www.askapache.com/seo/404-google-wordpress-plugin.html</guid>
		<description><![CDATA[<p><a class="IFL hs hs33" href="http://www.askapache.com/google-seo-wordpress-yaHOO-robots" rel="nofollow" title="404 Not Found page using Google Ajax Search API"></a><strong>1 minute Install!</strong><br />Turns every 404 Not Found error into a SEO traffic generating event! Now you have many unique users with unique IP addresses and cookies searching your blog on all of the Google Indexes... <strong>Sweet!</strong><br /><br /><a href="http://www.askapache.com/google-wordpress-plugin-htaccess-robots-php-plugin.html?linux=bsd&#38;g=354" rel="nofollow">&#171;Take My 404 for a Test-Drive</a><br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html#aademo">Demo</a> | <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html#aadl">Download</a> | <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html#aai">Installation</a> | <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html#aaf">FAQ</a> | <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html#aass">Screenshots / Video</a></p>
<p><strong>AskApache Google 404</strong> is a <strong>must-have</strong> WordPress plugin that uses some ajax and a couple tricks to display a very helpful and SEO Error Page.  The default displays Google Search Results for <strong>images, news, blogs, videos, web, custom search engine, and your own site</strong>.<br class="C" /></p>
<p class="bnote"><strong>Updated:</strong>  01/26/2008<br /><strong>Install Time:</strong>   10 seconds to 5 minutes<br /><strong>Install Difficulty:</strong>   Super Easy</p>
<h2><a id="aademo"></a>Demo 404 Error Page</h2>
<p><a class="IFL hs hs33" href="http://www.askapache.com/google-seo-wordpress-yaHOO-robots" rel="nofollow" title="404 Not Found page using Google Ajax Search API">Click Image</a><br class="C" /></p>
<p class="anote"><strong>Heads Up:</strong>  I&#8217;ve been thinking about ways to improve this plugin for awhile now, and I&#8217;m going to be releasing an upgrade in the coming weeks!  Any specific feature requests let me know~</p>
<h2><a id="aadl"></a>Downloads</h2>
<div class="dlarea">
<div class="dlin">
<ol>
<li><a href="http://wordpress.org/extend/plugins/askapache-google-404/">askapache-google-404</a></li>
</ol>
</div>
</div>
<h2><a id="aai">404.php Installation</a></h2>
<ol>
<li>Upload <code>zip/tar.gz</code> file to the <code>/wp-content/plugins/</code> directory and unzip.</li>
<li>Activate the plugin through the &#8216;Plugins&#8217; menu in WordPress.</li>
<li>Go to your Options Panel and open the &#8220;AA Google 404&#8243; submenu. <code>/wp-admin/options-general.php?page=askapache-google-404.php</code></li>
<li>Enter in your Google Search API Key and hit the &#8220;Update Key&#8221; Button. <a href="http://code.google.com/apis/ajaxsearch/signup.html">(Get One)</a></li>
<li>Add the code to your 404.php template page by including <code>&lt;?php if(function_exists(&#039;aa_google_404&#039;))aa_google_404();?&gt;</code> in your main content area.</li>
</ol>
<h2><a id="aaf"></a>Frequently Asked Questions</h2>
<p><strong>Do I need a Google Account?</strong></p>
<p>Yes.</p>
<p><strong>Do I need a 404.php template file?</strong></p>
<p>Only if you want to use this for your error page.</p>
<p><strong>My 404.php page isn&#8217;t being served for 404 Not Found errors!?</strong></p>
<p>Add <code>ErrorDocument 404 /index.php?error=404</code> to your .htaccess file.</p>
<p><strong>What is a Google API Key?</strong></p>
<p><a class="IFL" rel="lb" href='/wp-content/uploads/2007/09/aa-got-key.png' title='The Google Ajax API Key'><img src='/wp-content/uploads/2007/09/aa-got-key.thumbnail.png' alt='The Google Ajax API Key' /></a><br class="C" /></p>
<p><strong>How do I get a Google API Key?</strong></p>
<p><a class="IFL" rel="lb" href='/wp-content/uploads/2007/09/aa-get-key.png' title='Get Google API Key'><img src='/wp-content/uploads/2007/09/aa-get-key.thumbnail.png' alt='Get Google API Key' /></a><br class="C" /></p>
<h2><a id="aass"></a>Google 404 Screenshots</h2>
<p><span id="errorpage404" class="v601"><span class="load">Loading Video&#8230; <a href="http://f.askapache.com/mp4/">[dl]</a></span></span></p>
<p class="IFL"><strong>Plugin Configuration Panel</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-panel-preview1.png' title='AskApache Google 404 WordPress Plugin Configuration Panel'><img src='/wp-content/uploads/2007/09/aa-panel-preview1.thumbnail.png' alt='AskApache Google 404 WordPress Plugin Configuration Panel' /></a></p>
<p class="IFL"><strong>Search Entire Web</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-404-all-web.png' title='Search Entire Web with Google'><img src='/wp-content/uploads/2007/09/aa-404-all-web.thumbnail.png' alt='Search Entire Web with Google' /></a></p>
<p class="IFL"><strong>Search Blogs</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-404-blog-search.png' title='Search Blogs'><img src='/wp-content/uploads/2007/09/aa-404-blog-search.thumbnail.png' alt='Search Blogs' /></a></p>
<p class="IFL"><strong>Search Custom Search Engines</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-404-google-cse.png' title='Search Custom Search Engines'><img src='/wp-content/uploads/2007/09/aa-404-google-cse.thumbnail.png' alt='Search Custom Search Engines' /></a></p>
<p class="IFL"><strong>Search Images</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-404-image-search.png' title='Search Images'><img src='/wp-content/uploads/2007/09/aa-404-image-search.thumbnail.png' alt='Search Images' /></a></p>
<p class="IFL"><strong>Search Online Videos</strong><br /><a rel="lb" href='/wp-content/uploads/2007/09/aa-404-video-search.png' title='Search Online Videos'><img src='/wp-content/uploads/2007/09/aa-404-video-search.thumbnail.png' alt='Search Online Videos' /></a></p>
<hr />
<h2>More Info from Google</h2>
<ul>
<li><a href="http://code.google.com/apis/ajaxsearch/">AJAX Search API</a></li>
<li><a href="http://code.google.com/apis/ajaxsearch/wizards.html">AJAX Search Wizards</a></li>
<li><a href="http://code.google.com/apis/ajaxsearch/documentation/">Developer Guide</a></li>
<li><a href="http://code.google.com/apis/ajaxsearch/samples.html">Code Samples</a></li>
<li><a href="http://code.google.com/apis/ajaxsearch/community-samples.html">Community Samples</a></li>
<li><a href="http://code.google.com/support/bin/topic.py?topic=10021">Knowledge Base</a></li>
<li><a href="http://googleajaxsearchapi.blogspot.com/">AJAX APIs Blog</a></li>
<li><a href="http://groups.google.com/group/Google-AJAX-Search-API">Developer Forum</a></li>
</ul>
<p><a href="http://www.askapache.com/ajax/404-google-wordpress-plugin.html">SEO Boost from Google 404 Plugin</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/ajax/404-google-wordpress-plugin.html/feed/</wfw:commentRss>
		<slash:comments>112</slash:comments>
		</item>
		<item>
		<title>Crazy Cache WordPress Plugin Released</title>
		<link>http://www.askapache.com/wordpress/crazy-cache-wordpress-plugin.html</link>
		<comments>http://www.askapache.com/wordpress/crazy-cache-wordpress-plugin.html#comments</comments>
		<pubDate>Tue, 01 Apr 2008 05:25:23 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Cache]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=548</guid>
		<description><![CDATA[<p><a rel="lb" class="IFL" href='/wp-content/uploads/2008/04/crazy-cache.png'><img src="/wp-content/uploads/2008/04/crazy-cache-150x150.png" alt="AskApache Crazy Cache WordPress Plugin" title="AskApache Crazy Cache WordPress Plugin" width="150" height="150" /></a>A WordPress plugin that caches your entire blog for WP-Cache, I love this plugin and finally released it to the public!<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p>Isn&#8217;t <a href="http://wordpress.org/extend/plugins/wp-cache/">WP-Cache</a> an incredibly useful plugin?  If I was only allowed to have one plugin for my WordPress blogs, <strong>hands-down I&#8217;d choose <a href="http://wordpress.org/extend/plugins/wp-cache/">WP-Cache</a></strong>.</p>
<p class="cnote"><strong><a href="http://wordpress.org/extend/plugins/askapache-crazy-cache/">AskApache Crazy Cache</a> lets you cache all the posts on your blog at once</strong>.</p>
<p>I&#8217;ve used some advanced features of libcurl and fsockopen to make sure that this caching action doesn&#8217;t overwhelm your server or result in redundant requests.  That could slow down your blog, which I would never, ever, allow, I am very interested in this stuff.. <em>speedy sites that is</em>.</p>
<p><a rel="lb" class="IFL" href='/wp-content/uploads/2008/04/crazy-cache.png'><img src="/wp-content/uploads/2008/04/crazy-cache-150x150.png" alt="AskApache Crazy Cache WordPress Plugin" title="AskApache Crazy Cache WordPress Plugin" width="150" height="150" /></a>I always wanted the ability to cache all my posts on my blog whenever I wanted, and WP-Cache doesn&#8217;t let you do that.  So a few months ago I hacked together this kick-butt plugin to do exactly that.<br class="C" /></p>
<h2>ScreenShot</h2>
<p><a rel="lb" href='/wp-content/uploads/2008/04/crazy-cache.png'><img src="/wp-content/uploads/2008/04/crazy-cache-300x239.png" alt="AskApache Crazy Cache WordPress Plugin" title="AskApache Crazy Cache WordPress Plugin" width="300" height="239" /></a></p>
<h2>Installation</h2>
<p>This plugin is one of those idiot-proof installations, nuff said.</p>
<h2>Download</h2>
<ul>
<li><a href="http://wordpress.org/extend/plugins/askapache-crazy-cache/">askapache-crazy-cache at wordpress.org</a></li>
</ul>
<h2>Want More Speed?</h2>
<p>I love you guys and girls who want a faster Internet, we rock.  So check these out.</p>
<ul>
<li><a href="http://www.askapache.com/wordpress/wp-cache-speed-hack.html">Hack WP-Cache for maximum speed</a></li>
<li><a href="http://www.askapache.com/htaccess/speed-up-your-site-with-caching-and-cache-control.html">Caching with .htaccess &#8211; take your website and your skills to the next level</a></li>
<li><a href="http://www.askapache.com/css/background-image.html">CSS Image Sprites &#8211; All you need to get started in 5 mins</a></li>
<li><a href="http://www.askapache.com/web-cache/top-methods-for-faster-speedier-web-sites.html">The ultimate list to the ultimate methods of speeding up your site</a></li>
<li><a href="http://www.askapache.com/htaccess/mod_rewrite-fix-for-caching-updated-files.html">mod_rewrite caching trick to eliminate millions of 304 If Modified Since requests</a></li>
</ul>
<p><a href="http://www.askapache.com/wordpress/crazy-cache-wordpress-plugin.html">Crazy Cache WordPress Plugin Released</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/crazy-cache-wordpress-plugin.html/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>AskApache Password Protection, For WordPress</title>
		<link>http://www.askapache.com/wordpress/htaccess-password-protect.html</link>
		<comments>http://www.askapache.com/wordpress/htaccess-password-protect.html#comments</comments>
		<pubDate>Sat, 29 Mar 2008 13:02:57 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Plugins]]></category>

		<guid isPermaLink="false">http://www.askapache.com/wordpress/htaccess-password-protect.html</guid>
		<description><![CDATA[<p><a rel="lb" class="IFL" href="/wp-content/uploads/2008/03/screenshot-11.png"><img src='/wp-content/uploads/2008/03/screenshot-11-150x150.png' alt='AskApache Password Protect ScreenShot 1' /></a><strong>AskApache Password Protect</strong> adds some serious password protection to your WordPress Blog.  Not only does it protect your wp-admin directory, but also your wp-includes, wp-content, plugins, etc. plugins as well.  Imagine a HUGE brick wall protecting your frail .php scripts from the endless attacks of automated web robots and password-guessing exploit-serving scripts.<br class="C" /></p>
]]></description>
			<content:encoded><![CDATA[<p><a href="#aad">Description</a> | <a href="#aadl">Download</a> | <a href="#aai">Installation</a> | <a href="#aaf">FAQ</a> | <a href="#aass">Screenshots</a></p>
<p><a rel="lb" class="IFL" href="/wp-content/uploads/2008/03/screenshot-11.png"><img src='/wp-content/uploads/2008/03/screenshot-11-150x150.png' alt='AskApache Password Protect ScreenShot 1' /></a><strong>AskApache Password Protect</strong> adds some serious password protection to your WordPress Blog.  Not only does it protect your wp-admin directory, but also your wp-includes, wp-content, plugins, etc. plugins as well.  Imagine a HUGE brick wall protecting your frail .php scripts from the endless attacks of automated web robots and password-guessing exploit-serving virii.  Forget spam, these millions of zombie bots are too outrageous to ignore, they are attempting known <em>(but strangely outdated)</em> exploits looking for known vulnerabilities against blogs and other Internet software.  Sooner or later some poor blogger is going to <em>miss</em> an upgrade and become a victim to this type of video-game-like-attack. <br class="C" /></p>
<p>Of course this would never be able to stop real hacker intent on taking over your blog, if you are connected to the net on a public line, of course you coun&#8217;t stop them.  The people who are attacking the blogosphere are for the most part just playing.  They &#8220;hack&#8221; code that &#8220;exploits&#8221; a &#8220;vulnerabiliity&#8221; in some open-source software like phpBB or WordPress.   Those people actually help the community of open source software like WordPress by finding security issues and bringing them to light..  So who is this plugin built to stop?  It&#8217;s built to stop the people who are trying all the time to maliciously crack into YOUR average blog.  Why would someone want to hack an AVERAGE blog like mine or yours?  Well the answer is that its not an actual group, entity, or person who is going to try hacking into your blog.  Its an army of robots.. and they will never stop the attack.</p>
<p>So how do these robots attack us?  What is their ammo?  Their ammo is very specific knowledge of exploiting security holes in very specific software to &#8220;crack&#8221; your blog.  Vulnerabilities are discovered all the time, mostly small ones, but those vulnerabiilties that are dangerous to those of us running WordPress 2.5 are LETHAL to those of us running 2.1.. just absolutely deadly.  So These robots are programmed to do one thing and one thing only, try the exact same exploit that would work against 2.3 against every computer on the internet, as fast as they can and as anonymously as they can..  terrorizing the networks with these non-stop requests and slowing down the whole internet, which hopefully will start getting faster as more people use this plugin. Robots have no choice but to leave my servers alone.  They understand what a 403 Forbidden means, to them it means take me off your list, the exploit I&#8217;m carrying is not compatible.  But once again, this will not stop a hacker, this will stop 99.9% of the same bots that &#8220;hacked&#8221; 99.9% of the blogs.</p>
<h2><a id="aad"></a>Description</h2>
<p><a class="IFL" rel="lb" href="/wp-content/uploads/2008/03/screenshot-2.png"><img src='/wp-content/uploads/2008/03/screenshot-2-150x150.png' alt='AskApache Password Protect ScreenShot 1' /></a><strong>This Plugin will make alot of the bots out there stop coming back</strong>, and I have found this exact type of security setup to be a great insurance policy against these types of brainless zombie bots.  A few years ago I had implemented this password protection on a forum I was the security admin for, and it didn&#8217;t seem like a big improvement to very many people.  The forum software we were running was phpbb, and during that Christmas break we weren&#8217;t even thinking about the forums.   When we got back though the whole place was in an uproar.  Some kid sent out a million of these zombie robots with a single payload- an exploit that he knew would successfully penetrate the forum&#8217;s defenses. <em> It did.</em></p>
<p><strong>It was like a tidal wave across the world</strong>, thats how many of these phpBB forums were hit.  Thankfully all the kid did was copy the entire forum into a kind of book format, and sell it on ebay.    Anyway so we looked at the logs for our server and forum, and we saw he had tried the exact same thing against us&#8230; and he did have our forum software defenses beat&#8230; You see he had his target all scoped out and meticulously researched, a nice fat range of forums needing an upgrade.. As long as they could get to the inner door <em>(admin login)</em> they could knock it down in seconds and own the whole thing.</p>
<p>Everything about the attack on our server was incredibly smooth and fast, hacked past the user login and then flew straight towards the admininstrator login&#8230;  then, out of nowhere they got b**slapped because they ran full-speed into a wall that seemingly came out of nowhere, and thats exactly the same thing that you will have after installing this plugin.  Its like being surrounded by a smal army, a sniper can still get you, but you can forget about the ground troops <em>(zombies ech)</em><br class="C" /></p>
<p>If you are worried about your WordPress blog getting hacked, this can help immensely.  It adds a 2nd layer of security to your blog by requiring a username and password to access anything in the <code>/wp-admin/</code> folder.</p>
<p><strong>The plugin is simple</strong>, you just choose a username and password and you are done.  It writes the .htaccess file, without messing it up.  It also encrypts your password and creates the .htpasswd file, as well as setting the correct security-enhanced file permissions on both.</p>
<p><em>This plugin automatically picks all the right settings</em> for where to save the .htpasswd and .htaccess files, but you can easily change those settings to anything you want.  You can change it whenever you want right from your WordPress Admin Panel.</p>
<h2><a id="aass"></a>Screenshots</h2>
<p><a rel="lb" href='/wp-content/uploads/2008/04/screenshot-2.png'><img src="/wp-content/uploads/2008/04/screenshot-2.png" alt="New .htaccess security modules for wp-includes and wp-content" title="New .htaccess security modules for wp-includes and wp-content" /></a></p>
<p><a href='/wp-content/uploads/2008/03/screenshot-11.png'><img src="/wp-content/uploads/2008/03/screenshot-11-150x150.png" alt="WordPress 2.5 Compatible - AskApache Password Protect" title="WordPress 2.5 Compatible - AskApache Password Protect" /></a></p>
<p><a href='/wp-content/uploads/2008/03/screenshot-2.png'><img src="/wp-content/uploads/2008/03/screenshot-2-150x150.png" alt="" /></a></p>
<h2><a id="aadl"></a>Downloads</h2>
<p>Download the <a href="http://wordpress.org/extend/plugins/askapache-password-protect/">AskApache Password Protection Plugin</a></p>
<h2><a id="aai"></a>Installation</h2>
<ol>
<li><strong>Upload</strong> <code>aa-password-protect.zip</code> to the <code>/wp-content/plugins/</code> directory</li>
<li><strong>Unzip</strong></li>
<li><strong>Activate</strong></li>
<li><strong>Setup</strong></li>
</ol>
<h2><a id="aaf"></a>Frequently Asked Questions</h2>
<h3>Do I have to type in my username and password every admin page?</h3>
<p>No.  You just have to type it in once and it will keep you logged in until you close your browser.</p>
<hr />
<h3>How Secure Is It</h3>
<p>In <a href="http://www.rfc-editor.org/rfc/rfc2617.txt">Basic HTTP Authentication</a>, the password is passed over the network not encrypted but not as plain text &#8212; it is &#8220;uuencoded.&#8221; Anyone watching packet traffic on the network will not see the password in the clear, but the password will be easily decoded by anyone who happens to catch the right network packet.</p>
<h2>WordPress Codex Security Articles</h2>
<ul>
<li><a href="http://codex.wordpress.org/htaccess_for_subdirectories">Securing directories with .htaccess</a></li>
<li><a href="http://codex.wordpress.org/Hardening_WordPress">Hardening WordPress</a></li>
</ul>
<blockquote cite="http://codex.wordpress.org/Hardening_WordPress">
<ol>
<li><strong>Limiting access:</strong> Making smart choices that effectively lower the possible entry points available to a malicious person.</li>
<li><strong>Containment:</strong> If a weak point in your installation is found by a malicious person, your system should be configured to minimize the amount of damage that can be done once inside your system.</li>
<li><strong>Knowledge:</strong> Keeping backups, knowing the state of your WordPress installation at regular time intervals, documenting your modifications all help you understand your WordPress installation.</li>
</ol>
</blockquote>
<p><a href="http://www.askapache.com/wordpress/htaccess-password-protect.html">AskApache Password Protection, For WordPress</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/htaccess-password-protect.html/feed/</wfw:commentRss>
		<slash:comments>86</slash:comments>
		</item>
		<item>
		<title>Update: AskApache Password Protect Plugin</title>
		<link>http://www.askapache.com/wordpress-plugins/securing-htaccess-plugin.html</link>
		<comments>http://www.askapache.com/wordpress-plugins/securing-htaccess-plugin.html#comments</comments>
		<pubDate>Thu, 07 Feb 2008 14:51:29 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[WordPress Plugins]]></category>

		<guid isPermaLink="false">http://www.askapache.com/wordpress-plugins/securing-htaccess-plugin.html</guid>
		<description><![CDATA[<p><a class="IFL" rel="lb" href='/wp-content/uploads/2008/02/screenshot-1.png' title='The Plugin Control Page'><img src='/wp-content/uploads/2008/02/screenshot-1.thumbnail.png' alt='The Plugin Control Page' /></a>WordPress plugin gives you control over HTTP Basic Authentication for your WordPress blog which among other things, stops most automated hacking attempts and exploits being attempted, cutting down on the number of requests, connections, and mysql queries for all WordPress blogs on the Internet.  <br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p class="cnote"><strong>Note:</strong>  A lot of updates to this plugin are in the works, so this plugin should be considered <strong>BETA</strong>&#8230; than them.</p>
<p>Adding .htaccess based HTTP Basic Authentication to your WordPress blog is such a smart thing to do and I&#8217;m trying to help make it easier for you.  Mainly because it stops alot of automated hacking attempts and exploits from ever being attempted, thus cutting down on the number of requests, connections, and mysql queries for all WordPress blogs on the Internet.</p>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-1.png' title='The Plugin Control Page'><img src='/wp-content/uploads/2008/02/screenshot-1.png' alt='The Plugin Control Page' /></a></p>
<p class="anote"><strong>Upgrading Instructions</strong><br />Just download and extract the new plugin file to <code>wp-content/plugins/askapache-password-protect/</code> and activate it.  It automatically deactivates and deletes <a href="http://www.askapache.com/wordpress/htaccess-password-protect.html">previous</a> versions.</p>
<h2>New Features</h2>
<p>Well, this is BETA for now, meaning it works but there are a lot of cool features I just didn&#8217;t have time to include in this release.  A lot of people were experiencing problems with the older version.</p>
<ul>
<li>TONS of error checking and compatibility checks. This plugin WONT break your server.</li>
<li>Tests your servers ability to use .htaccess/.htpasswd files by setting them up in a temporary spot first and checking them. <em>(ssl/https enabled)</em></li>
<li>Determines which .htpasswd Encryption Algorithms that your server supports by testing each one.</li>
<li>Provides all 4 htpasswd encryption formats that <a href="http://httpd.apache.org/docs/trunk/misc/password_encryptions.html">Apache explains</a></li>
<li>Uses php to generate the encrypted hashes for all 4 encryption formats using portable code. Even has the apache-specific MD5!</li>
<li>Allows you to specify and change the AuthName / Realm</li>
<li>I made this upgrade fool-proof, just the way I like it.</li>
</ul>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-4.png' title='Easy Upgrade and Installation'><img src='/wp-content/uploads/2008/02/screenshot-4.png' alt='Easy Upgrade and Installation' /></a></p>
<h2>Download New AskApache PassPro</h2>
<p>Now hosted by WordPress.org</p>
<p>Current AskApache Password Protection: <a href="http://downloads.wordpress.org/plugin/askapache-password-protect.zip">download</a> | <a href="http://wordpress.org/extend/plugins/askapache-password-protect/">description</a></p>
<h2>Whats Looks Like</h2>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-1.png' title='The Plugin Control Page'><img src='/wp-content/uploads/2008/02/screenshot-1.thumbnail.png' alt='The Plugin Control Page' /></a></p>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-21.png' title='WordPress Security Plugin: Various Option Panels on Plugin Setup Page'><img src='/wp-content/uploads/2008/02/screenshot-21.thumbnail.png' alt='WordPress Security Plugin: Various Option Panels on Plugin Setup Page' /></a></p>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-3.png' title='The HTTP Basic Authentication Password Prompt'><img src='/wp-content/uploads/2008/02/screenshot-3.thumbnail.png' alt='The HTTP Basic Authentication Password Prompt' /></a></p>
<p><a rel="lb" href='/wp-content/uploads/2008/02/screenshot-4.png' title='Easy Upgrade and Installation'><img src='/wp-content/uploads/2008/02/screenshot-4.thumbnail.png' alt='Easy Upgrade and Installation' /></a></p>
<p class="anote"><strong>Install Problems</strong><br />Known solutions to all the issues are in the works so prepare for the next release.  In the meantime, the problem occurs because this version tries to save the encrypted htpasswd file ABOVE your document_root, obviously this isn&#8217;t working very well for most wordpress users.</p>
<p><a href="http://www.askapache.com/wordpress-plugins/securing-htaccess-plugin.html">Update: AskApache Password Protect Plugin</a> originally appeared on AskApache.</p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress-plugins/securing-htaccess-plugin.html/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
