Forum Moderators: phranque

Message Too Old, No Replies

need .htaccess magic

         

henry2

2:15 am on Apr 1, 2009 (gmt 0)

10+ Year Member



Folks:

I need .htaccess magic to accomplish the following three goals:

Goal 1. All references of forms like

www.example.com/*.php
www.example.com/*.html
www.example.com/*.htm
example.com/*.php
... etc. etc.

are rewritten to

www.example.com/site-down-for-maintenance.html

Note: I may not need to bother with variants like ".htm" if I don't have any at all on my site. I'll double-check such cases.

Goal 2. I want the _option_ to allow references to certain file types to go through unchanged, for example:

www.example.com/*.jpg

may or may not be re-written to the

www.example.com/site-down-for-maintenance.html

In other words, I'm looking for extension-by-extension control.

Goal 3. Any references to any subdomain are never re-written. For example,

subdomain3.example.com/foo.html
subdomain3.example.com/*.php
subdomain3.example.com/*.html
subdomain3.example.com/*.htm
... etc. etc.

should be untouched.

The following code ALMOST does the trick:

....
RewriteEngine on

RewriteOptions MaxRedirects=15

rewritecond %{http_host} ^(www\.)?example\.org$ [nc]

RewriteRule ^(.*)\.html closed-message.html [L,nc] #html
RewriteRule ^(.*)\.htm closed-message.html [L,nc] #htm
RewriteRule ^(.*)\.php closed-message.html [L,nc] #php
RewriteRule ^(.*)\.jpg closed-message.html [L,nc] #jpg
RewriteRule ^(.*)\.tiff closed-message.html [L,nc] #tif
RewriteRule ^(.*)\.gif closed-message.html [L,nc] #gif
<eof>

Well, it works if I comment out some of the rewrite rules, or if I increase the Maxdirects value significantly. Otherwise the error log complains:

...mod_rewrite: maximum number of internal redirects reached. Assuming configuration error. Use 'RewriteOptions MaxRedirects' to increase the limit if neccessary.

I don't see a large number of internal redirects. What incredibly obvious/amazingly subtle point am I missing?

TIA,

Henry

jdMorgan

3:46 pm on Apr 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You are rewriting "closed-message.html" to itself, since it ends in ".html". This results in recursion and eventually causes the server error. Do not set your MaxRedirects above five if you wish the user to see server-side error messages. If the limit is set above five, the browser will give up first and print it's own error message, and the user won't see the server's error message.

Also, you cannot rewrite image types to html pages -- The browser cannot handle this, since images are normally embedded in <img> tags *on* pages. If you wish to handle directly-linked images, then make a small image with the "Closed for maintenance" message in it, and rewrite image requests to that file in the same way that we rewrite page requests here.

In addition, RewriteConds affect only the single rule that follows them, so your subdomains likely *are* being affected by your second through last rule. Since only one rule is actually required, this problem is easily eliminated.

Finally, do not put comments on the same line as code. Doing so will result in server Warnings, which take up CPU time whether they are logged or not.

I'd suggest:


# Rewrite .html, .htm, and .php page requests in main domain to maintenance page, unless already done
RewriteCond %{HTTP_HOST} ^(www\.)?example\.org [NC]
RewriteCond %{REQUEST_URI} !^/closed-message\.html$
RewriteRule \.(html?Šphp)$ closed-message.html [NC,L]

Replace the broken pipe "Š" characters with solid pipe characters before use; Posting on this forum modifies the pipe characters.

Completely flush your browser cache before each test to avoid being confused by stale cached results.

Jim

henry2

8:15 pm on Apr 1, 2009 (gmt 0)

10+ Year Member



Jim:

Thanks!

I annotated your suggestion, made a very few changes, and put it into action.

Clearly I was not straight about two major points: (1) The scope of RewriteConds and (2)the re-processing of modified URIs. I'm still not clear on the second, but now I know it occurs, so I'll seek more information about it.

Hmmm, more generally, I suppose I ought to seek information about issues in de-activing a website, especially one that's been breached. I think that mapping all php and html to a single page _should_ be sufficient, but know enough to know there are usually finer points to miss.

Thanks!

Henry

jdMorgan

9:00 pm on Apr 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



mod_rewrite in a per-directory (.htaccess) context behaves recursively; If any RewriteRule is invoked, mod_rewrite directive processing is re-started from the top. Therefore, you must explicitly prevent unwanted pattern matches on previously-rewritten or redirected URLs.

The [L] flag stops mod_rewrite precessing only for the current pass through the mod_rewrite directives, and as such cannot prevent this recursion. However, for performance reasons, [L] should still be used on every rule unless you have a specific reason not to use it.

What you need to do in response to a server breach depends on the method used to breach the server. Therefore, identifying the attack vector(s) is job #1. Generally, change all passwords (for *all* access methods, e.g. HTTP, FTP, SFTP, shell, etc.), disable all unneeded and/or unnecessary protocols, services, script interpreters, and applications, and make sure all scripts and script interpreters (e.g. PHP interpreter, database, blog and forum software) are the most-current production versions.

Going further, make sure that all scripts and 'security filters' are based on whitelisting rather than blacklisting. To be clear, make sure that when filtering user input, you accept only what you are willing to accept, rather than coding to reject specific malformed inputs. In the former case, you may accidentally reject valid input, resulting in a complaint, while in the latter case, you may allow a hack to take place, resulting in a compromised server -- and possibly, in compromised user data. So, decide what you want to allow, rather than trying to identify everything that you might want to block.

In the most restrictive cases, you can simply allow only alphanumeric characters, underscore and hyphen, and only the most common punctuation characters in user input; Reject, delete, escape, encode, or replace all other characters.

Jim

g1smd

9:19 pm on Apr 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



*** de-activing a website ***

I would serve 404 status and appropriate page content for these requests, not return 200 OK for every request - infinite duplicate content.

henry2

2:02 am on Apr 2, 2009 (gmt 0)

10+ Year Member



Jim:

Thanks for your response.

Thanks for the .htaccess processing sum-up. I think I've got it now -- those particular points, anyway. (I'm sure there are plenty more issues about .htaccess that I'm clueless about.)

About the breach: I'm taking over a neglected website that uses an early and very outdated version of PHP-Fusion, 6.00.303. Apparently that's a security sieve. The PHP-Fusion folks listen impatiently to the symptoms I describe and tell me it is not worthwhile looking further.

My plan is to upgrade to the latest version, take the usual overall precautions --protecting directories and setting appropriate file permissions on critical files, etc.-- and assure regular oversight and maintenance of the site.

---

g1smd:

Thanks for your suggestion to serve 404 and content.

I've have in mind got a relatively harmless and probably impractical scheme to squeeze some functionality out of the site with the driving PHP (PHP-Fusion) disabled. That's why I'm serving duplicate content -- if the scheme works out, some of it may become differentiated. With luck, I'll have the site fully updated and secured within two weeks.

---

Thanks,

Henry

g1smd

8:44 am on Apr 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I misunderstood what you meant by "deactivating".

jdMorgan

3:30 pm on Apr 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You might also want to look at the 503-Service Unavailable response, with an eye to correctly informing the search engines as to the status of your server.

503 Service Unavailable

The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay may be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.

Jim

henry2

5:46 pm on Apr 2, 2009 (gmt 0)

10+ Year Member



jdMorgan:

Thanks for your response.

Sure, why not return 503? Except, I haven't a clue how to do it. A clue, please?

I might add: Our site does not seem to be at all dependent on search engines. (But: very briefly, how would we verify that?)

Thanks,

Henry

g1smd

6:05 pm on Apr 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Make sure you sign up for Google WebmasterTools and Google Analytics or similar to see what is going on.

jdMorgan

9:01 pm on Apr 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



On Apache 2.x, try this:

# Return 503-Service Unavailable status for .html, .htm, and .php page requests in main domain
RewriteCond %{HTTP_HOST} ^(www\.)?example\.org [NC]
RewriteRule \.(html?Šphp)$ - [NC,R=503,L]
#
# Set Retry-After header on all .htm, .html, and php page responses
<FilesMatch "\.(html?Šphp)">
Header set Retry-After: "Fri, 17 Apr 2009 23:59:59 GMT"
</FilesMatch>

Be exceedingly cautious about the correctness of the Retry-After date format and the consistency of the day with the date.

Replace broken pipe "¦" characters with solid pipes, as usual.

Jim