I have a question about stopping spoofed form submissions. How about if by using the $_SERVER['HTTP_REFERER']
I only allow submissions to my forms coming from my website? Would that help?! Thanks!

- 188,624
- 52
- 326
- 405

- 77
- 1
- 5
-
3`HTTP_REFERER` is untrusted it's easy to prepare a request with custom referer – veritas Feb 08 '12 at 23:08
-
read: http://stackoverflow.com/questions/233192/detecting-stealth-web-crawlers – Jacco Feb 09 '12 at 13:20
11 Answers
It would help, and it's fairly easy thing to add but it wont stop a targeted attack, after all you can spoof a HTTP_REFERER
header.
One thing to keep in mind is that a client is not required to send a HTTP_REFERER
, so if the header is missing you might want to allow submissions anyway. If this is not possible, then checking HTTP_REFERER
wont help you.
Run a search for CAPTCHA "Completely Automated Public Turing test to tell Computers and Humans Apart", this is what you're really looking for.

- 57,230
- 10
- 89
- 128
Let us be clear: it's technically impossible to prevent spoofed form submissions. Summing it up in one sentence:
If your browser can do it, everyone can do it.

- 15,015
- 6
- 52
- 90
-
2Technically true, but it is possible to prevent form submission without a previous GET. I would hate to see people conclude that it isn't possible in the general case and thus fail to take the necessary steps to prevent Cross Site Request Forgeries (XSRF). – David Conrad Feb 08 '12 at 23:13
-
1I think that depends on the conditions that you establish. If the session is authenticated, secure and reasonably short, cookies are encrypted, proper techniques (antiforgery tokens, for example) are used, you can set the bar very high in preventing spoofed forms. – tvanfosson Feb 08 '12 at 23:22
-
To add to tvanfosson / David Conrad's comments. If you make sure that any sensitive data needing to be changed in the database, especially password / email like fields require the user to enter their password in and does not use $_GET / $_REQUEST to access the variables, that would help out with XSRF and other easy spoofs / exploit attempts. On the XSRF side, I think not using $_GET / $_REQUEST for account requests would solve most of those issues. – Jim Feb 08 '12 at 23:26
-
@BradFJacobs – CSRF is neither limited to GET requests nor to single requests. It takes just some little more effort to set up an attack for a multi-step transaction with POST requests. – Gumbo Feb 09 '12 at 09:37
The main issues with form spoofing is that you don’t have any control over what the client sends. The user could change any form parameter. So everything the client sends on form submission needs to be validated and verified.
This also means, the less parameters you provide to be send in the form, the less you need to validate and verify. Particularly parameters that are preset and not to be changed by the user (i. e. hidden form fields) don’t need to be embedded into the form if not really necessary. Instead you could store them in a container in the session and only refer to this container via a hidden field. If this is not an option, make sure that you at least can detect any integrity flaw by singing the preset values with a MAC.
Another issue is that the form parameters that need to be send for a successful form submission are quite predictable so that an attacker could send repeatedly valid form submissions. If you would require a non-predictable parameter that can only be issued by your server and is validated on form submission, you could verify that the form submission is granted.
One solution would be to use a random one-time token that is generated on form request and is stored in the session as well as put into the form as a hidden input field. Then on form submission you check if a token was provided and whether it is equal to the one stored in the session; if they are equal, the you remove the token from the session and process the form, otherwise you deny the form processing.
Frankly, this mechanism is not perfect as you could still request the form first and then send a spoofed form data. That’s where you could use additional Captchas or other mechanisms that prevent automatic requests.
The best would be to use a combination of all measures mentioned above:
- create a form container in the session with a sufficiently random identifier; put that identifier as a hidden input field in the form to identify the form container on form submission
- store any preset parameters in the form container instead of the form
- if preset parameters cannot be excluded from the form, authenticate its value with a MAC (use a per form container key)
- if there are suspiciously repeated form requests/form submissions, think of additionally using Captchas to prevent automatic requests
Additionally, these session based form containers do also prevent CSRF as their identifiers are unpredictable for an attacking third party.
A suggestion would be to use a token. If you are using any of the popular MVC architectures, you do not need to worry as spoofing prevention is taken care of. But if you are on a custom MVC Architecture like myself, a token is an approach. In your Database class, for every CRUD(CREATE, READ, UPDATE AND DELETE) function, check for the token. e.g the token can be generated via md5.
public function save(){
if(isset($_SESSION['token']){
//proceed with saving
}else{
//kill it,
die;
}
}
Alternatively, you can easily integrate your web application with this Cross-Site Request Forgery protection kit. Check it out here

- 4,783
- 4
- 18
- 27
Stop? No. Limit? Possibly. Is your website really being hit with an alarming number of spoofed form submissions, or are you just being preemptive? Don't solve problems that aren't there.

- 188,624
- 52
- 326
- 405
-
3Security is a problem that is always there. If spoofed form submissions would be a problem, it is appropriate to guard against them, even before the first incident. – David Conrad Feb 08 '12 at 23:09
The referrer is easily spoofed.
You should validate the form best you can to catch out stupid bots, and possibly use a server side CAPTCHA.

- 479,566
- 201
- 878
- 984
Referer is easy to spoof, so any attacker that wanted to spoof a form submission could just spoof the Referer header as well. Also, I don't believe web browsers are required to send the Referer header, so it could potentially exclude form posts from legitimate users.

- 15,432
- 2
- 42
- 54
Spoofing HTTP headers is pretty easy and so shouldn't be used for something that requires rigorous security. One technique typically used is to send both an encrypted cookie and a matching, encrypted token in a hidden input on the form. The cookie should be an HTTP-only cookie. On form submission check that the value from the cookie and the value from the hidden input match. This will help prevent cross-site request forgeries since a request to your site can't be successfully made from another site because they'll either be missing the cookie (for a MIM attack) or the hidden input (spoofed form). Of course, this depends on you making sure your site is otherwise secure so they can't sniff the tokens to find out what to supply.
Here's a nice discussion on how this is done in ASP.NET MVC, http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

- 524,688
- 99
- 697
- 795
Without definition of "spoofing" it would be but empty talk.
There are a dozen of different "spoofs", each with it's different protection.
Most general solution is CAPTCHA.

- 156,878
- 40
- 214
- 345
Doesn't really help. Read this: http://shiflett.org/articles/form-spoofing

- 3,814
- 1
- 17
- 9
-
-
-
If it is just a link, comments is the appropriate place to post them. Comments don't solicit upvotes. – Jacco Feb 09 '12 at 17:15