Prevent form post request from another domain in PHP

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.

20 thoughts on “Prevent form post request from another domain in PHP

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

  2. 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. 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. 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. 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. 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

    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. @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

    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. Thanks tedivm and other friends for commenting…I’ll surely update date post with the best method

  11. 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. 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. 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. @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

    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.

  16. Oliver

    captcha is one extra thing the visitor has to do. it goes against the basics of user experience to require them to fill in a field that has nothing to do with what they’re actually trying to achieve.

  17. griffin

    Misleading post. A very dangerous and unprofessional advice. You must warn your readers in the post itself.

  18. First of all, there’s no point to fight over 100% or 0%, there’s no 100% way to prevent spam. If your browser can view the page and submit a valid form so can they.

    I think the programmer should do everything he/she can to prevent it.

    Referrer check COULD and will help against some spammers.

    So does a cookie/session, I would just add a key to the session on the same page in which the form is displayed to make sure the form was actually displayed then check if it exists on submit. Pretty simple and useful!

  19. Adeel

    hello,

    do web hosting have some kind of security that they prevent the posting from other domain?

    like i have a web hosting and url is http://somedomain.com/mypage.php

    now if someone trying to post the data form http://someotherdomain.com

    will web hosting stop that post ? or i can able to receive it?

    thank you

  20. This is bad idea…
    Someone can use hiding HTTP-referer function, or can use another PHP-script to set fake-referer.

Leave a Reply

Your email address will not be published. Required fields are marked *

*