Forum Topic: Confused with methods

Forum: .htaccess Forum : Redirecting • Posted by Leon Fernandez • Updated:

What sometimes confuses me, is that a specific task for rewrites for example is expressed diferently on diferrent sources.

For example, consider denying post request if they are not originated from our domain (I think it means to avoid somebody trying to post from outside our website, probably a direct bot hit or replicating our post forms maybe).

Found several methods and they are a bit differently crafted, which would be considered a better method?

Method 1 (protocol in referer, pages begin with .* and ends in $, uses request post, rule does not use parenthesis):

# secure forms via referrer check
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_REFERER} !^http://yourdomain.com/.*$ [NC]
RewriteCond %{REQUEST_POST} .*contact_us.php$ [NC,OR]
RewriteCond %{REQUEST_POST} .*comments.php$ [NC,OR]
RewriteCond %{REQUEST_POST} .*register.php$ [NC,OR]
RewriteCond %{REQUEST_POST} .*login.php$ [NC]
RewriteRule .* - [F]
</IfModule>

Method2 (no protocol in referer, pages begin with . and ends in *, extensions are escaped, uses request method and uri):

# deny access to no referrer request
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .contact_us\.php* [OR]
RewriteCond %{REQUEST_URI} .comments\.php* [OR]
RewriteCond %{REQUEST_URI} .register\.php* [OR]
RewriteCond %{REQUEST_URI} .login\.php*
RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) - [F]
</IfModule>

8 Replies to “Confused with methods”

Jeff Starr
Posted by Jeff Starr

First thing when in doubt: test, test, test. Test both sets of rules on a test/development environment. That may or may not narrow it down. That said, if both/all techniques accomplish the same functional result, then it becomes a matter of syntax, which may vary significantly and may or may not affect functionality.

For example, if we test both of the above techniques, we should find the following main functional differences:

- Secure forms rules: deny requests for any of the four specified pages unless they are coming from our own site.

- No referrer rules: the exact same as the previous technique, only with a couple more conditions required, namely that the type of request be POST, and that the user agent must not be empty/blank.

Then after testing and figuring out the differences in functionality, you can go in and scrutinize differences in syntax, which may also affect functionality. For example, in the first technique:

RewriteCond %{HTTP_REFERER} !^http://yourdomain.com/.*$ [NC]

While in the second, we have:

RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]

Here, the first rule will not match https:// or http://www., should they happen; while the second will pretty much match anything on the specified domain. Likewise there are other subtle differences such as [NC] vs. [OR], etc.

I hope this helps shed some light on it.. let me know if there is anything specific or if I can elaborate on anything.

Leon Fernandez
Posted by Leon Fernandez •

Thanx alot for the explanation, very clear, I tested them both and only the second method worked in every case match as supposed to (didnt think about the mismatched elements like www).

Now is there anyway to match a wildcard for all files on the server when somebody tries a POST on them, instead of directly matching each specific file name?

I tried out simply:

RewriteCond %{REQUEST_URI} *

... but got an internal error.

Jeff Starr
Posted by Jeff Starr

Sure, try something like this:

<IfModule mod_rewrite.c>
	RewriteCond %{THE_REQUEST} ^POST(.*)HTTP/1\.1$ [NC]
	RewriteRule .* - [F,L]
</IfModule>

That matches POST requests happening via HTTP 1.1. You can adjust the regex to account for 1.0 and older protocols as desired. Use caution with this technique, it will prevent forms from working, along with any scripts that normally do POST requests.

Leon Fernandez
Posted by Leon Fernandez •

Yeah, I can see that it would block any post request, probably good for a static site, but I was referring to the previous method, where any file on the site needed to be loaded from within the site and not externally.

So it would be something like mentioned about for the second method but with a wild card for all files on the server, maybe like this I guess? (dont know why Im missing something here):

<IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteCond %{REQUEST_METHOD} POST
     RewriteCond %{REQUEST_URI} .*         
     RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]
     RewriteCond %{HTTP_USER_AGENT} ^$
     RewriteRule (.*) - [F]
</IfModule>

What I mean here is using this code insted of the previous one that mentioned every single file that has a post handler (contactus.php, register.php, login.php, comments.php, this.cfm, that.cgi, ahother.html, etcetera.php) if you know what I mean.

In other words its like saying #Doesnt matter what you request#, but it has to be made while you are inside my site and not from an external source.

Jeff Starr
Posted by Jeff Starr

Something like this?

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{HTTP_REFERER} !(.*)example\.com(.*) [NC]
RewriteRule .* - [F]
</IfModule>

Every POST must be made from example.com in this technique.

EDIT: replaced [OR] with [NC].

Leon Fernandez
Posted by Leon Fernandez •

Ohhh, even more simple than I thought. Thank you sir.

I supposes that it can work for every page as you mention except when you have a case where an external script that you use needs to to write on a specific space in a form, in which case it would block it as well (for example an external antispam program) ?

And with that supposition, I also guess that all you have to do is add the additional like inside that statement as so:

....
RewriteCond %{HTTP_REFERER} !(.*)externalservice\.com(.*) [OR]
....
Jeff Starr
Posted by Jeff Starr

That should work, but note that I changed the [OR] to [NC] in the previous example. Make sure to do the same for any additional referrer directives, like so:

RewriteCond %{HTTP_REFERER} !(.*)externalservice\.com(.*) [NC]

Otherwise the logic is off and the technique will fail.

Leon Fernandez
Posted by Leon Fernandez •

I didnt see that (blind I am at times), with an OR it would exlude my site or external site, never consider both as an option, thanx for the clarification...