3

I'm not an .htaccess expert, so I beg your pardon for the basic question.

In a website I'm working on there's a form. The action URL of the form is a file placed in the root of the website.

I want to deny the direct access to this file (from the address bar of the browser, CURL and/or any other way I can't figure out) but the file must still be usable by the form (so the POST request coming from the form must not be blocked).

I tried this extreme approach:

<Files "_mf.php">
Order Allow,Deny
Deny from all
</Files>

What I want to know is if I can exclude any referrer that is not the page where is located the form and if this is a good approach.

5

Just to clarify, there is no fool-proof way to restrict access in this instance (unless this is all behind some kind of authentication) since it needs to be accessible to your form. All you can do is prevent casual browsing. Anyone that really wants to submit requests to this script can do.

<Files "_mf.php">
Order Allow,Deny
Deny from all
</Files>

The problem with this, as you probably found out, is that it blocks all requests, including POST requests from your form submission. What you could do is wrap this in a <LimitExcept> wrapper, so that it applies only to non-POST requests:

<limitExcept POST>
  <Files "_mf.php">
    Order Allow,Deny
    Deny from all
  </Files>
</LimitExcept>

Any GET requests (eg. "from the address bar of the browser") will be blocked (403 Forbidden). As well as any PUT, DELETE, CONNECT, OPTIONS, etc. etc. requests. But POST requests will be allowed through unhindered.

If you want to check the HTTP referer as well, then you could resort to mod_rewrite. For example:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} !POST [OR]
RewriteCond %{HTTP_REFERER} !^http://example.com/
RewriteRule ^_mf\.php - [F]

Where example.com is your canonical hostname. You could instead specify the exact URL of the referring page (the page that contains your form) if you wish:

RewriteCond %{HTTP_REFERER} !^http://example.com/path/to/file-that-contains-form$

This would need to go near the top of your .htaccess file.

What this says is... for all requests to /_mf.php that are either not POST requests or the HTTP Referer is not your domain then serve a 403 Forbidden.

Note that this comes with caveats. It's possible that the user's browser is not set to send HTTP Referers - your script will not be accessible to those users. (This is rare, but some "power" users might choose to do this.)

Any user with CURL know-how can still fake the request and submit requests to your script without accessing your form. Since they can submit a POST request and fake the HTTP referer.

14
  • Good answer, but it doesn't limit POST requests. If I create a form on my site and POST it to the form on the OPs site it will more than likely submit. I know this because I have used it for mischeivous purposes in the past :P – Steve Mar 27 '17 at 21:23
  • @Steve: in my case, the file has some protections inside: validation of content (JSON/not JSON, presence of mandatory JSON keys, referrer test, test for a session variable, test for POST request, say not HEAD/PUT/etc.). Moreover, the file is not linked to anything (I suppose only who uses the form from the backend can get its URL) – 3000 Mar 28 '17 at 5:52
  • "I suppose only who uses the form from the backend can get its URL" - Or anyone who checks the HTML source? Checking the HTTP Referer (as in the mod_rewrite method above) does at least prevent a form from simply being embedded in an external website and pointing to your script (like @Steve mentions) - unless the referer is masked by the browser. "test for a session variable" - and this certainly makes it that much harder again. – MrWhite Mar 28 '17 at 21:45
  • @w3dk: who checks the HTML source IS a registered user of the website, the HTML of that page is not public, that HTML is generated only when a user is logged in :-) – 3000 Mar 29 '17 at 6:10
  • @w3dk: I forgot to mention (besides the session) I set a cookie too on form submit (I don't know if this is "fakeble" too, but I did it anyway) – 3000 Mar 29 '17 at 6:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.