tags:

views:

124

answers:

5

I was wondering is there a way in PHP that you could tell where a form was submitted without using hidden fields or anything of the like where the user would only need to tamper with the html a little? For example i am trying to work out if a form that was submitted was actually on my website or whether the form was saved offline and submitted that way.

A: 

You can't really tell. Why would it matter? If you're trying to detect if someone has forged a request, you can't.

Amended: The green solution above does help some issues, but it doesn't address the question of if it came from your site, or if it was modified.

Andy Lester
Anti-CSRF Token?
jfar
A: 

I could be wrong but wouldn't the referrer header tell you this?

rein
Assuming it is set (not always the case) and not spoofed.
Sylverdrag
+1  A: 

You can attempt to use the referral header set in HTTP requests, do note however that not all browsers set these correctly, or users have them turned off, or that they are very easily spoofed.

Without a hidden field containing an unique identifier that is used to identify the form for that one single submission there is no good way of identifying whether the form is being forged or not.

X-Istence
+3  A: 

An hidden field is not easily spoofed if it contains a UID (if you encrypt a time stamp you will be able to tell how long the user has been on the page)

Of course the user can enter whatever he wants in the field, but unless he can generate a valid UID, he can't make your php script believe it came from somewhere else.

You can also track a user's visited pages through $_SESSION and use that instead of the HTTP referrer (store each visited page in an array inside $_SESSION, and when your script is called, you simply check whether the last page was yours? Variation of that are possible depending on what you need).

Sylverdrag
Just wanted to ad a link I researched while typing up my answer: http://shiflett.org/articles/cross-site-request-forgeries You beat me to it Sylver. ;)
jfar
Thank you very much, this seems to be the best idea out of the bunch, thank you to those that suggested referrer header as well :)
Marc Towler
A: 

This gets you what you are after:

$referer = ($SERVER["HTTP REFERER"] == null);

This actually fetches it from the HTTP Header where it looks like this:

...
Referer: http://foobar.com/page.php
...

It is easy for anyone to spoof this but for most purposes it is reasonable.

Trivia: Referer should actually be spelt referrer which is the correct spelling but the spelling mistake made its way into the HTTP specification and has stuck since.

aleemb
As others above pointed out, I have read that some browsers (I don't know which ones) doesn't set this field, or set it incorrectly. So rejecting a request because referer isn't correct might lead to lock some users out. And on the other side, somebody wanting to submit arbitrary form content will probably think of setting correctly this field...
PhiLho
@PhilLho, I am not aware of any browsers that have this incorrectly implemented. In fact, this is very trivial to get right so I am fairly certain you won't have issues with browser implementations.In either case, I thought you were just asking for a code snippet for PHP. A stricter implementation of this would use "nonce keys" sent as hidden input fields. These cannot be manipulated.
aleemb