Skip to content

Instantly share code, notes, and snippets.

@chrisdempsey
Last active June 4, 2019 22:56
Show Gist options
  • Save chrisdempsey/7a1c7b865d8404b9a40e to your computer and use it in GitHub Desktop.
Save chrisdempsey/7a1c7b865d8404b9a40e to your computer and use it in GitHub Desktop.
web.config for Wordpress by SAOTN
<!-- source: https://www.saotn.org/my-wordpress-web-config/ -->
<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
<configSections>
<!--
Load HttpBL assembly to keep suspicious and malicious web robots
out. Get your Access Key @ https://www.projecthoneypot.org/create_account.php
-->
<section name="HttpBL" type="HttpBL.Settings" />
</configSections>
<appSettings/>
<!--
Configure HttpBL settings, choose what is best for your situation
-->
<HttpBL
Enabled="true"
AlwaysAllow=""
AlwaysDeny=""
AccessKey="xyzabc"
QueryDomain="dnsbl.httpbl.org"
MaxAge="30"
MaxScore="40"
CacheTTL="7200"
CacheWhite="true"
RedirectOnHit="false"
RedirectURL="/denied.aspx?ip=$IP&amp;result=$RESULT"
Logging="false"
LogPath="\path\to\HttpBL\logfile"
LogHits="false" />
<system.webServer>
<modules>
<!--
If installed (server wide), remove the Helicon Ape module because
the module can eat quite a bit of RAM per worker process
-->
<remove name="Helicon.Ape" />
<!--
Add the HttpBL .NET module
-->
<add name="HttpBL" type="HttpBL.HttpBL" />
<!--
IIS caching modules for URI-, file- and authentication tokens
-->
<add name="UriCacheModule" />
<add name="FileCacheModule" />
<add name="TokenCacheModule" />
</modules>
<!--
We need to set a mimeType for javascript there, so configure some
other types too. Notice minFileSizeForComp, this specifies the
minimum number of kilobytes a file must contain in order to use
on-demand compression
-->
<httpCompression minFileSizeForComp="0">
<scheme
name="gzip"
dll="%Windir%\system32\inetsrv\gzip.dll"
staticCompressionLevel="7" />
<dynamicTypes>
<clear/>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="*/*" enabled="false" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
<add mimeType="application/x-font-ttf" enabled="true" />
<add mimeType="application/octet-stream" enabled="true" />
</dynamicTypes>
<staticTypes>
<clear/>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
<add mimeType="application/x-font-ttf" enabled="true" />
<add mimeType="application/octet-stream" enabled="true" />
</staticTypes>
<!--
urlCompression can give issues under certain circumstances
-->
<urlCompression
doStaticCompression="true"
doDynamicCompression="true"
dynamicCompressionBeforeCache="true" />
</httpCompression>
<!--
Browser cache (or client cache), and mimeMappings for IIS
-->
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="28.00:00:00" />
<remove fileExtension=".html" />
<mimeMap fileExtension=".html" mimeType="text/html;charset=UTF-8" />
<remove fileExtension=".css" />
<mimeMap fileExtension=".css" mimeType="text/css" />
<remove fileExtension=".htm" />
<mimeMap fileExtension=".htm" mimeType="text/html;charset=UTF-8" />
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<remove fileExtension=".js" />
<mimeMap fileExtension=".js" mimeType="application/x-javascript;charset=UTF-8" />
<remove fileExtension=".svg" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>
<!--
Remove all in IIS configured defaultDocuments, and
add the ones that are necessary. This speeds up finding the defaultDocument.
-->
<defaultDocument>
<files>
<clear/>
<add value="index.php" />
<add value="index.html" />
</files>
</defaultDocument>
<!--
Remove and add some response headers
-->
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<remove name="Vary" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="X-UA-Compatible" value="IE=Edge,chrome=1" />
</customHeaders>
</httpProtocol>
<handlers>
<!--
Remove the existing PHP fastCgi handler, so we can add our own
-->
<remove name="PHP" />
<!--
My PHP5.5 WinCache PHP handler in IIS, the scriptProcessor path is
specific to my environment. Due to a file system cache bug in
WinCache v1.3.7.4 for PHP 5.6, PHP 5.5/WinCache is my fallback until I
have found the time to test a newer WinCache version for PHP 5.6.
See @ https://www.saotn.org/php-wincache-on-iis/ for more
PHP WinCache configuration information
-->
<add name="PHP"
path="*.php"
verb="*"
modules="FastCgiModule"
scriptProcessor="\path\to\php55\php-cgi.exe|-c \path\to\php55\php.wincache.ini"
resourceType="File"
allowPathInfo="true"
requireAccess="Script"
responseBufferLimit="0" />
</handlers>
<!--
Here we configure URL rewrites. For example, we can block referers,
block access to wp-comments-post.php or wp-login.php, and all our WordPress
rewrites go here.
-->
<rewrite>
<!--
Block out some known spam referrers
-->
<rule name="block_spam_referrers" stopProcessing="true">
<matchurl="(.*)" ignoreCase="true" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?make-money-online\.7makemoneyonline\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?buttons-for-your-website\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?buttons-for-website\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?ranksonic\.info.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?youmaydownloadthem\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?o-o-6-o-o\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?realforexgeminicodereviews\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://s\.click\.aliexpress\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?androidfirmware\.science.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?best-seo-offer\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?best-seo-solution\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?cenoval\.ru.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?pornhub-forum\.ga.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?buy-cheap-online\.info.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?get-free-traffic-now\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?hulfingtonpost\.com.*" negate="false" />
<add input="{HTTP_REFERER}" pattern="https?://(www\.)?semalt\.semalt\.com.*" negate="false" />
</conditions>
<action type="CustomResponse"
statusCode="403"
statusReason="Forbidden: Access is denied."
statusDescription="Access to this website from the site you came from is prohibited!" />
</rule>
<!--
Start WordPress Multisite rewrite rules
-->
<rule name="WordPress RewriteRule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="WordPress RewriteRule 2" stopProcessing="true">
<match url="^wp-admin$" ignoreCase="false" />
<action type="Redirect" url="wp-admin/" redirectType="Permanent" />
</rule>
<rule name="WordPress RewriteRule 3" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress RewriteRule 4" stopProcessing="true">
<match url="^(wp-(content|admin|includes).*)" ignoreCase="false" />
<action type="Rewrite" url="{R:1}" />
</rule>
<rule name="WordPress RewriteRule 5" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
<action type="Rewrite" url="{R:2}" />
</rule>
<rule name="WordPress RewriteRule 6" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>
<!--
WordPress Permalinks URL Rewrite
Disabled in favor of WordPress Multisite
-->
<!--
<rule name="wordpress" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
-->
</rules>
<outboundRules>
<!--
Remove Server response header
-->
<rule name="Remove Server header">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
<!--
Configure HSTS for HTTPS
-->
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
<!--
Block out some known offending IP addresses. Unfortunately, it is almost
impossible to keep this up-to-date
-->
<security>
<ipSecurity>
<add ipAddress="193.201.224.96" allowed="false" />
<add ipAddress="185.19.92.163" allowed="false" />
<add ipAddress="37.128.149.238" allowed="false" />
<add ipAddress="37.59.151.190" allowed="false" />
<add ipAddress="176.10.104.96" allowed="false" />
<add ipAddress="202.6.19.50" allowed="false" />
<add ipAddress="178.162.209.133" allowed="false" />
<add ipAddress="178.162.205.23" allowed="false" />
<add ipAddress="155.133.18.127" allowed="false" />
<add ipAddress="190.172.12.239" allowed="false" />
<add ipAddress="195.154.235.59" allowed="false" />
<add ipAddress="195.154.232.169" allowed="false" />
<add ipAddress="62.210.140.103" allowed="false" />
<add ipAddress="87.66.111.150" allowed="false" />
<add ipAddress="175.126.100.17" allowed="false" />
<add ipAddress="103.23.201.170" allowed="false" />
<add ipAddress="202.164.234.1" allowed="false" />
</ipSecurity>
<!--
IIS Request Filtering rules.
Block out some requests to known backdoors (or vulnerable scripts).
Watch out: names can vary...
-->
<requestFiltering>
<denyUrlSequences>
<add sequence="ofc_upload_image.php" />
<add sequence="timthumb.php" />
<add sequence="img.php" />
<add sequence="img_x.php" />
<add sequence="thumb.php" />
<add sequence="phpthumb.php" />
<add sequence="kontol.php" />
<add sequence="magic.php.png" />
<add sequence="food.php" />
<add sequence="ph.php" />
<add sequence="fragile.php" />
<add sequence="3xp.php" />
<add sequence="explore.php" />
<add sequence="petx.php" />
<add sequence="dl-skin.php" />
<add sequence="direct_download.php" />
<add sequence="getfile.php" />
<add sequence="vito.php" />
<add sequence="upload_settings_image.php" />
<add sequence="saint.php" />
<add sequence="lunar.php" />
<add sequence="nyet.gif" />
<!-- /& URI -->
<add sequence="/&amp;" />
<add sequence="/login.php" />
<add sequence="magmi.php" />
</denyUrlSequences>
<!--
Yes, even your WordPress site can get scanned for Joomla com_jce vulnerabilities..
-->
<denyQueryStringSequences>
<add sequence="option=com_jce&amp;task=plugin&amp;plugin=imgmanager&amp;file=imgmanager&amp;version=1576&amp;cid=20" />
<!--
You can add Query String sequences below, for example to (try to) block some SQL injection
or Cross Site Scripting attacks, but only through HTTP GET:
-->
<add sequence="action=revslider_show_image&amp;img=../wp-config.php" />
</denyQueryStringSequences>
<!--
Block SQL injection attacks through IIS Request Filtering filtering Rules.
These are merely examples to show you the power of IIS and Request Filtering
http://www.iis.net/configreference/system.webserver/security/requestfiltering/filteringrules
-->
<filteringRules>
<filteringRule name="prevent SQL injection"
scanUrl="true"
scanQueryString="true">
<appliesTo>
<clear />
<add fileExtension=".php" />
</appliesTo>
<denyStrings>
<add string="@" />
<add string="select" />
<add string="table" />
<add string="update" />
<add string="--" />
<!-- ... -->
<!-- ... -->
</denyStrings>
</filteringRules>
</requestFiltering>
</security>
</system.webServer>
<!--
WordPress wp-login.php security: IP address whitelist,
all IP addresses not listed below are denied access to /wp-login.php
-->
<location path="wp-login.php">
<system.webServer>
<security>
<ipSecurityallowUnlisted="false">
<add ipAddress="111.11.111.1" allowed="true" />
<add ipAddress="111.111.1.111" allowed="true" />
</ipSecurity>
</security>
</system.webServer>
</location>
<!--
Disable PHP execution in WordPress uploads folder, for extra security.
-->
<location path="wp-content/uploads">
<system.webServer>
<handlers accessPolicy="Read"/>
</system.webServer>
</location>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment