Prevent form post request from another domain in PHP

Posted on June 22, 2008 
Filed Under php, php attack, tips and technique

HTTP POST request from outside domain is one of the way of attacking your website. A intruder can use JavaScript in other domain or localhost to send the repetitive POST request to your web page  containing PHP script. We must prevent this kind of cross domain form posting which might be harmful of our website.

 

Example of form post a spam

Let’s suppose that, we have a contact form in our website and we’re posting the detail of the form to “contact.php” file. A intruder can use JavaScript in another domain and can send the repetitive post request by placing “http://our-site/contact.php” in the action field of their code and spam our website.

How to check the form being posted from another domain

Last time, I’ve posted the article about useful server variables in PHP. Among them, we can use HTTP_REFERRER server variables to prevent the cross domain form post request. You can look at the  example code in PHP below to check the POST request is from the same domain or different domain.

//if example.com is there in HTTP_REFERRER variable
if(strpos($_SERVER['HTTP_REFERER'],'example.com'))
{
  //only process operation here
}

HTTP_REFERRER variable is used here to check where the post request came from. Then, along with strpos() function of PHP, we can check weather the HTTP_REFERRER variable contains our domain as a referrer website or not. If the post request is from our domain then only we can execute the remaining code of our page.

A better approach

The HTTP_REFERRER headers can be disabled or faked and we can’t rely 100% on it.But, we can also use cookie to check for the cross-site post request forgery. And, you know that cookies are also unreliable anyway.

One of the better approach will be to use use a hidden field in the form which contains the md5() value of a salt (a secret value stored in the database) with another dynamic value like session id or IP address of the user and verifying it with PHP when the post request of that form comes in PHP.

Popularity: 10% [?]

Enter your email address and get recent tutorials, tips, tricks and scripts of PHP, Ajax, JavaScript and CSS directly delivered to you email inbox:

Follow me on twitter at http://twitter.com/roshanbh.

Related Posts

» Prevent your website being displayed inside IFRAME
» How to solve the problem of retrieving same value by Ajax - Browser Cache Problem
» Contact Me
» Smart contact form for your websites

Comments

15 Responses to “Prevent form post request from another domain in PHP”

  1. arty on June 22nd, 2008 10:36 am

    Better would be something like if(_SERVER['HTTP_REFERER'] && strpos($_SERVER['HTTP_REFERER'],’example.com’)) …

  2. Roshan on June 22nd, 2008 10:44 am

    good point man…..that would be better if the contact.php page contains the html form, if this page only contains the codes to be executed when form is posted i.e page doesn’t contain html form then we can only use the if(strpos($_SERVER['HTTP_REFERER'],’example.com’)) becauase this page is surely going to have HTTP_REFERRER server variable…

  3. Gromitt on June 22nd, 2008 3:19 pm

    The value of PHP $_SERVER['HTTP_REFERER'] is totally unreliable as it can be modified by the one which requested the page, and this can be achieved in many ways :

    * through specific browser or browser + specific extension.
    * through CURL with the “CURLOPT_REFERER” option
    * through a raw HTTP query
    * …

  4. Roshan on June 23rd, 2008 5:02 am

    I agree that HTTP headers can be faked and it’s true that we can’t 100% rely on the HTTP headers as it can be faked easily…

  5. arty on June 23rd, 2008 2:33 pm

    The point is that some users may have referers disabled, like myself. The referer check is, if its activated, a good start to prevent cross-site request forgeries …

  6. Soren on June 23rd, 2008 9:23 pm

    Its trivial to send HTTP_REFERER for the spambot programs, so “not 100% reliable” is more like 0% reliable.

    For real solutions, look at eg. the wikipedia page: http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention

  7. tedivm on June 24th, 2008 9:05 am

    Where did you hear that there was not a 100% reliable way of preventing cross site forgery? Did you bother doing any research at all before coming up with this post?

    A rather simple way to prevent them is to require a posted variable (called a token) with each form that can’t be easily guessed by the site attempting the hack. A simple way to generate the token could be to create an md5 out of the session id and the form name (or the user name and form name).

  8. Roshan on June 24th, 2008 4:39 pm

    @tedivm - Ok I agree that your idea is somewhat ok but not 100% secure.Form name, session id , user name everything is visible to intruder. Do you think it is 100% secure ?

    A intruder can easily view the source of the form see the name as well as he can look at the cookie to view the session id and guess the token with a few effort and with staying in that site he can easily post the value of token from a faked form…

  9. tedivm on June 24th, 2008 6:00 pm

    If an intruder already has the session id then its game over, they can steal that session. What your suggesting is the equivalent of stealing someones key but picking the lock anyways.

    So lets think about this- how can the attacker get the session id? The easiest method would be to just sniff it, but that would require that they either be in the immediate area (in the case of wireless) or that they somehow break into a computer or router between the website your defending and the computer itself. Of course, both these methods are completely thwarted by a little thing called SSL.

    Outside of that it gets a little more difficult, especially if some simple steps are taken in the program itself (tying the session id to an ip address and browser string, for instance).

    In the future, before posting things like this, you may want to consider doing actual research. Most of the stuff I (and others) have brought up are pretty fundamental to PHP security and you could have easily found this information had you actually looked.

  10. Roshan on June 24th, 2008 6:46 pm

    Thanks tedivm and other friends for commenting…I’ll surely update date post with the best method

  11. Joost Pluijmers on June 25th, 2008 7:49 am

    The best protection against form forgery is an appliance of HMAC. You know your going to serve a form, so why not put an encrypted token in an hidden field? When the form gets submitted you validate that against the token saved in the session for that user. Simple yet effective.

    Using this method you can also expire the actual submitted form. So brute forcing the key will be useless as well.

    The only real way this method gets cracked is if the users session id gets compromised.

  12. arty on July 2nd, 2008 7:20 pm

    I also would suggest a pool of several tokens for a single user. If a user uses tabs he makes his old generated forms useless if you just overwrite your old token. So give the user about 5-10 tokens as max and delete them if they are used.

  13. Joost Pluijmers on July 3rd, 2008 2:32 pm

    Iam currently developing a fool proof token alternator. This means that within a set time frame a new token is generated for the site, how is this different? Because this token system won’t break the active sessions. Iam creating some sort of window algorithm for it, where within this window you get assigned a new token.

    Iam planning to use this as a seed for HMAC, per-page keys and maybe even session id’s. This just guarantees several things:
    - The request really comes from my domain.
    - Nearly eliminates brute force attacks.
    - Replay attacks will also be gone due to page-keys.

    Now I just need to figure out a good solution against session fixation. ;)

  14. Roshan on July 3rd, 2008 4:44 pm

    @Joost - All the best for the developing full proof soloution for token alternator and hope to get the good soultion against session fixation…

    if you find the better solution don’t forget to post that here as well..

  15. Joe on July 21st, 2008 4:13 pm

    Why don’t you guys use image captcha? this concept has been used since the year 2000 to protect automatic post or bruteforce attack, even this comment form i’m posting right now is using captcha spam protection. but it is text based captcha wont achieve 100% protection.

Leave a Reply