<?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>Circles and Crosses &#187; Wordpress</title>
	<atom:link href="http://ox.no/posts/tag/wordpress/feed" rel="self" type="application/rss+xml" />
	<link>http://ox.no</link>
	<description>Håvard Stranden&#039;s website</description>
	<lastBuildDate>Sat, 20 Aug 2011 00:11:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>&#8220;Hiding&#8221; WordPress installation files</title>
		<link>http://ox.no/posts/hiding-wordpress-installation-files</link>
		<comments>http://ox.no/posts/hiding-wordpress-installation-files#comments</comments>
		<pubDate>Mon, 03 Apr 2006 10:50:14 +0000</pubDate>
		<dc:creator>Håvard</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://ox.no/posts/hiding-wordpress-installation-files</guid>
		<description><![CDATA[By default, all the WordPress installation files are readable from a browser. What happens if example.com&#8216;s WordPress installation is at /wordpress/, and you go to http://example.com/wordpress/wp-content/plugins/ with your browser? Yes, you&#8217;re browsing the plugin directory. Obviously, changing permissions is not &#8230; <a href="http://ox.no/posts/hiding-wordpress-installation-files">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>By default, all the WordPress installation files are readable from a browser. What happens if <code>example.com</code>&#8216;s WordPress installation is at <code>/wordpress/</code>, and you go to <code>http://example.com/wordpress/wp-content/plugins/</code> with your browser? Yes, you&#8217;re browsing the plugin directory. Obviously, changing permissions is not going to work, but it is possible to obscure the access to the files (hence &#8220;hiding&#8221;). Read on for details.<!-- more --></p>

<h3>The WordPress default</h3>

<p>Let us start by looking at a &#8220;standard&#8221; WordPress <code>.htaccess</code> file, to understand how requests are handled in a typical WordPress installation:
<pre lang="apache"><ifmodule>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]</ifmodule></pre>
This file contains a few directives for Apache. The <code>&lt;ifmodule&gt; ... &lt;/ifmodule&gt;</code> tags tell Apache to care about their contents only if the specified module is installed. The remaining lines do the following:</p>

<ol>
<li>Start the mod_rewrite engine.</li>
<li>Set the base for rewrite paths (the root of the web directory in this case). All paths will be interpreted as being below the path in this directive.</li>
<li>If the file name the request maps to is not a file&#8230;</li>
<li>&#8230;and it is not a directory&#8230;</li>
<li>Then let it through to WordPress&#8217; <code>index.php</code> for further handling.</li>
</ol>

<p>This effectively means that as long as the request is <em>not</em> for a file or a directory below your web directory root, then WordPress handles it. If it <em>is</em> for a file or a directory, then Apache handles it (it falls through all the rewriting rules). This means that Apache will serve any file or directory as long as it can be read, which of course includes the WordPress installation files.</p>

<h3>The solution</h3>

<p>The desired situation is that people should only be able to read this files through &#8220;indirect&#8221; requests from your website, and not by accessing them directly. This can be achieved through a simple check of the <a href="http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html" title="HTTP Request Headers">HTTP Referer header</a> :
<pre lang="apache"><ifmodule>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !^https?://(www.)?example.com/.* [NC]
RewriteRule ^/?wordpress/?.* http://example.com/ [NC,L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [NC,L]
</ifmodule></pre>
As you can see, two directives have been added to the default <code>.htaccess</code> file. They state the following:</p>

<ol>
<li>If the request did not come from a reference on the website, then&#8230;</li>
<li>If the request was for a WordPress installation file, then redirect the request to the root of my website with a 301 response (moved permanently).</li>
</ol>

<p>This rather simple and elegant solution denies direct access to the WordPress installation files from browsers.</p>

<!--adsense-->

<h3>Why does it say &#8220;hiding&#8221;?</h3>

<p>Because people are still able to spoof the referer header to access your installation, meaning that it&#8217;s not an unbreakable solution.</p>

<h3>Caveats</h3>

<p>The drawback of this setup is mainly that denying direct access to the installation files means that you cannot access <em>any</em> of the files directly. This includes direct access to any images or other files you have uploaded, your administrator pages, etc.</p>

<p>To allow access to specific files and/or folders below your directory, add the following lines to your <code>.htaccess</code> file for each file or folder <em>below</em> the first <code>RewriteCond</code> line:
<pre lang="apache">RewriteCond %{REQUEST_URI} !^/some/directory/or/file</pre></p>

<p>Note that this last example is case-sensitive, so be accurate. Also note that if the rule is for a folder, you should include <code>/?</code> at the end, to make sure the rule matches requests for both <code>/some/folder</code> and <code>/some/folder/</code>.</p>

<p>Another caveat is that this makes your blog inaccessible to people who don&#8217;t send referrer headers. If you think that people should be allowed not to do so, then don&#8217;t implement the solution in this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://ox.no/posts/hiding-wordpress-installation-files/feed</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
	</channel>
</rss>

