SitePoint Sponsor

User Tag List

Results 1 to 24 of 24
  1. #1
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Form Post Hijaking

    Hi,

    I have recently seen some attempts at Form Hijaking I sure most are familiar with this as it is pretty rampant at the moment (some info here)

    I have a standard form that I use and would like to stop these attempts for obvious reasons - however my PHP skills aren't up to the task. If somebody could look at the code of my form and offer the best solution I would much appreciate this -

    Code:
    <?php
    if ($_POST) {
    if (get_magic_quotes_gpc()) {
    foreach ($_POST as $key => $value) {
    $temp = stripslashes($value);
    $_POST[$key] = $temp;
    }
    }
    
    if(($_POST['fullname'] == '') || ($_POST['tel'] == '')) {
    $error = '<strong>Sorry</strong>, You seem to have missed out some required fields:';
    if($_POST['fullname'] == '') {
    $error_fullname = ' <br /><strong>Full Name</strong> is a required Field';
    }
    if($_POST['tel'] == ''){
    $error_tel = ' <br /><strong>Telephone</strong> is a required Field';
    }
    
    }
    else{
    
    $to = 'info@mydomian.co.uk';
    $subject = 'Website form';
    // message goes here
    $message = "Full Name: " . $_POST['fullname'] . "\n";
    $message .= "Telephone: " . $_POST['tel'] . "\n";
    $message .= "Email: " . $_POST['email'] . "\n";
    $message .= "Message: " . $_POST['message'] . "\n";
    
    // headers go here
    $headers = "From: " . $_POST['email'] . "\n";
    $headers .= "Content-type: text/plain; charset=UTF-8";
    $sent = mail($to, $subject, $message, $headers);
    $autorespond = mail($_POST['email'], "Form Auto Response.", "Thank you for contacting Me, your message has been received and we will contact you shortly.", "From: info@mydomian.co.ukk<info@mydomian.co.ukk>");
    }
    }
    ?>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    
    <head>
    <title></title>
    </head>
    <body>
    
    <?php
    if (isset($sent)) {
    echo '<p><span class="thanks"><strong>Thank you</strong> for contacting Tablets of Stone.</span></p>';
    }
    else{
    echo '<p class="sorry"><!-- -->';
    echo $error;
    echo $error_fullname;
    echo $error_tel;
    echo '</p>';
    }
    ?>
    
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <fieldset>
    <legend>Feedback Form</legend>
    <div class="row">
    <span class="formLabel"><label for="fullname">Full Name*</label><br /></span>
    <input class="inputfield" type="text" id="fullname" name="fullname" size="30" />
    </div>
    <div class="row">
    <span class="formLabel"><label for="tel">Telephone*</label><br /></span>
    <input class="inputfield" type="text" id="tel" name="tel" size="30" />
    </div>
    <div class="row">
    <span class="formLabel"><label for="email">Email Address</label><br /></span>
    <input class="inputfield" type="text" id="email" name="email" size="30" />
    </div>
    <div class="row">
    <span class="formMessage">Message<br /></span>
    <textarea class="inputarea" name="message" rows="5" cols="30"></textarea>
    </div>
    </fieldset>
    <p><input type="submit" class="inputsend" name="SUBMIT" value="Send Form" /></p>
    </form>
    
    </body>
    </html>
    Thank You

  2. #2
    SitePoint Evangelist praetor's Avatar
    Join Date
    Aug 2005
    Posts
    479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    To prevent some form of code injection you can use the following
    Code:
    if (!preg_match('/^[a-zA-Z\._\-0-9]+?@[a-zA-Z\._\-0-9]+?\.[a-zA-Z\._\-0-9]{2,3}$/',$_POST['email'])) die('Invalid email format');
    at the begining of the script.

  3. #3
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi,
    The code you posted is definitely vulnerable to header-injection because of the $_POST['email'] ending up in the headers unfiltered.
    PHP Code:
    $headers "From: " $_POST['email'] . "\n"
    The function offered by praetor is a good way to ensure the mail address looks like a valid emailaddress.
    If you want to do more, you could insert a function like this:
    PHP Code:
    // function by Andrew Krespanis
    function isInjection($text) {
          
    $text strtolower($text);
          if (
    preg_match('#(content\s*-\s*disposition)|(bcc\:)|(cc\:)|(content\s*-\s*transfer\s*-\s*encoding)|(mime\s*-\s*version)|(multipart\s*/\s*mixed)|(multipart\s*/\s*alternative)|(multipart\s*/\s*related)|(reply\s*-\s*to)|(x\s*-\s*mailer)|(x\s*-\s*sender)|(x\s*-\s*uidl)#is',$text))
          { return 
    true; }
          else
          { return 
    false;}
    }
    // is there any email injection attempt?
    if( isInjection($_POST['fullname']) || isInjection($_POST['tel']) || isInjection($_POST['email']) || isInjection($_POST['message'])) { 
           
    $error_message[]  = "Email injection attempt!";
      }

    // here you could place even more checking ...


    // if there are no errors continue 
    if(count($error_message) ==0) { 
          
    // proceed to mail() 



    Now, if anything that's entered in one of the fields looks like an injection attempt, an error message is returned and no mail is sent.

  4. #4
    dooby dooby doo silver trophybronze trophy
    spikeZ's Avatar
    Join Date
    Aug 2004
    Location
    Manchester UK
    Posts
    13,788
    Mentioned
    151 Post(s)
    Tagged
    3 Thread(s)
    good suggestions, use 'em both and you will be smiling
    Mike Swiffin - Community Team Advisor
    Only a woman can read between the lines of a one word answer.....

  5. #5
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks guys will look into both suggestions

  6. #6
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay I have added the code as above (both options as recommended) just want to confirm that I have them in the correct places.

    PHP Code:
    <?php
    if ($_POST) {
    if (
    get_magic_quotes_gpc()) {
    foreach (
    $_POST as $key => $value) {
    $temp stripslashes($value);
    $_POST[$key] = $temp;
    }
    }

    // function by praetor
    if (!preg_match('/^[a-zA-Z\._\-0-9]+?@[a-zA-Z\._\-0-9]+?\.[a-zA-Z\._\-0-9]{2,3}$/',$_POST['email'])) die('Invalid email format');

    if((
    $_POST['fullname'] == '') || ($_POST['tel'] == '')) {
    $error '<strong>Sorry</strong>, You seem to have missed out some required fields:';
    if(
    $_POST['fullname'] == '') {
    $error_fullname ' <br /><strong>Full Name</strong> is a required Field';
    }
    if(
    $_POST['tel'] == ''){
    $error_tel ' <br /><strong>Telephone</strong> is a required Field';
    }
    }
    else{

    // function by Andrew Krespanis 
    function isInjection($text) { 
          
    $text strtolower($text); 
          if (
    preg_match('#(content\s*-\s*disposition)|(bcc\:)|(cc\:)|(content\s*-\s*transfer\s*-\s*encoding)|(mime\s*-\s*version)|(multipart\s*/\s*mixed)|(multipart\s*/\s*alternative)|(multipart\s*/\s*related)|(reply\s*-\s*to)|(x\s*-\s*mailer)|(x\s*-\s*sender)|(x\s*-\s*uidl)#is',$text)) 
          { return 
    true; } 
          else 
          { return 
    false;} 

    // is there any email injection attempt? 
    if( isInjection($_POST['fullname']) || isInjection($_POST['tel']) || isInjection($_POST['email']) || isInjection($_POST['message'])) {
           
    $error_message[]  = "Email injection attempt!"
      } 

    // if there are no errors continue 
    if(count($error_message) ==0) { 
          
    // proceed to mail() 
          


    $to 'info@copious.co.uk';
    $subject 'Website form';
    // message goes here
    $message "Full Name: " $_POST['fullname'] . "\n";
    $message .= "Telephone: " $_POST['tel'] . "\n";
    $message .= "Email: " $_POST['email'] . "\n";
    $message .= "Message: " $_POST['message'] . "\n";

    // headers go here
    $headers "From: " $_POST['email'] . "\n";
    $headers .= "Content-type: text/plain; charset=UTF-8";
    $sent mail($to$subject$message$headers);
    $autorespond mail($_POST['email'], "Form Auto Response.""Thank you for contacting Me, your message has been received and we will contact you shortly.""From: info@mydomian.co.ukk<info@mydomian.co.ukk>");
    }
    }
    ?>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">

    <head>
    <title></title>
    </head>
    <body>

    <?php
    if (isset($sent)) {
    echo 
    '<p><span class="thanks"><strong>Thank you</strong> for contacting Tablets of Stone.</span></p>';
    }
    else{
    echo 
    '<p class="sorry"><!-- -->';
    echo 
    $error;
    echo 
    $error_fullname;
    echo 
    $error_tel;
    echo 
    '</p>';
    }
    ?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <fieldset>
    <legend>Feedback Form</legend>
    <div class="row">
    <span class="formLabel"><label for="fullname">Full Name*</label><br /></span>
    <input class="inputfield" type="text" id="fullname" name="fullname" size="30" />
    </div>
    <div class="row">
    <span class="formLabel"><label for="tel">Telephone*</label><br /></span>
    <input class="inputfield" type="text" id="tel" name="tel" size="30" />
    </div>
    <div class="row">
    <span class="formLabel"><label for="email">Email Address</label><br /></span>
    <input class="inputfield" type="text" id="email" name="email" size="30" />
    </div>
    <div class="row">
    <span class="formMessage">Message<br /></span>
    <textarea class="inputarea" name="message" rows="5" cols="30"></textarea>
    </div>
    </fieldset>
    <p><input type="submit" class="inputsend" name="SUBMIT" value="Send Form" /></p>
    </form>

    </body>
    </html>
    Quick question does $error_message[] = "Email injection attempt!"; send an email indicating an injection attempt to the mail recipient or $to = 'info@mydomian.co.uk';?

    Thank you for your help

  7. #7
    SitePoint Enthusiast
    Join Date
    Nov 2005
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, so first of all, stripslashes must be called before executing an sql query.

    That's because if you have some validation error, and you will show the values the user entered, then the data will be altered.

    Second of all, you need to validate every field. (if it's an email, number, string, etc).

    A sql injection article can be found here.


    http://www.askbee.net/articles/php/S...injection.html

  8. #8
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi pixelpyro, a quick answer:
    $error_message[] = "Email injection attempt!";
    $error_message[] is an array which holds all the errors. So you can use more error functions in a row, and each time something is not valid you return an error. This way you can add as many error checks as possible, and in the end you check if the error_message array is not empty. If it is empty, you let the script proceed to the mail function.

    Secondly, I'm not sure what is meant with this advise
    stripslashes must be called before executing an sql query
    If you're going to perform an sql query you will have to escape the data before placing it in the query. With an mysql database you can use the function mysql_real_escape_string. But there's no mention of a query in your code, so this doesn't apply to your situation.

  9. #9
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I adjusted the code a bit and it seems to work like this:
    PHP Code:
    <?php
    // function by Andrew Krespanis
    function isInjection($text) {
          
    $text strtolower($text);
          if (
    preg_match('#(content\s*-\s*disposition)|(bcc\:)|(cc\:)|(content\s*-\s*transfer\s*-\s*encoding)|(mime\s*-\s*version)|(multipart\s*/\s*mixed)|(multipart\s*/\s*alternative)|(multipart\s*/\s*related)|(reply\s*-\s*to)|(x\s*-\s*mailer)|(x\s*-\s*sender)|(x\s*-\s*uidl)#is',$text))
          { return 
    true; }
          else
          { return 
    false;}
    }
    // declare an empty error array
    $error_message = array(); 

    // if form submitted
    if (isset($_POST['SUBMIT'])) 
      {
        if (
    get_magic_quotes_gpc()) {
          foreach (
    $_POST as $key => $value
              {
            
    $temp stripslashes($value);
            
    $_POST[$key] = $temp;
          }
      }

      
    // function by praetor
      
    if (!preg_match('/^[a-zA-Z\._\-0-9]+?@[a-zA-Z\._\-0-9]+?\.[a-zA-Z\._\-0-9]{2,3}$/',$_POST['email'])) 
      {
        
    $error_message[] = 'Invalid email!';
      }

      if((
    $_POST['fullname'] == '') || ($_POST['tel'] == '')) 
      {
         
    $error_message[] = '<strong>Sorry</strong>, You seem to have missed out some required fields:';
      }
      
      if(
    $_POST['fullname'] == ''
      {
        
    $error_message[] = ' <br /><strong>Full Name</strong> is a required Field';
      }
      
      if(
    $_POST['tel'] == '')
      {
        
    $error_message[] = ' <br /><strong>Telephone</strong> is a required Field';
      }
      
      
    // is there any email injection attempt?
      
    if( isInjection($_POST['fullname']) || isInjection($_POST['tel']) || isInjection($_POST['email']) || isInjection($_POST['message'])) {
           
    $error_message[]  = "Email injection attempt!";
      }

    // if there are no errors continue
    if(count($error_message) ==0
      {
      
    // proceed to mail()
      
    $to 'info@mydomian.co.ukk';
      
    $subject 'Website form';
      
    // message goes here
      
    $message "Full Name: " $_POST['fullname'] . "\n";
      
    $message .= "Telephone: " $_POST['tel'] . "\n";
      
    $message .= "Email: " $_POST['email'] . "\n";
      
    $message .= "Message: " $_POST['message'] . "\n";

      
    // headers go here
      
    $headers "From: " $_POST['email'] . "\n";
      
    $headers .= "Content-type: text/plain; charset=UTF-8";
      
    $sent mail($to$subject$message$headers);
      
    $autorespond mail($_POST['email'], "Form Auto Response.""Thank you for contacting Me, your message has been received and we will contact you shortly.""From: info@mydomian.co.ukk<info@mydomian.co.ukk>");
      }

    ?>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">

    <head>
    <title></title>
    </head>
    <body>

    <?php
    if (isset($sent)) 
      {
      echo 
    '<p><span class="thanks"><strong>Thank you</strong> for contacting Tablets of Stone.</span></p>';
      }



    if (isset(
    $error_message)) 
      {
        echo 
    '<p class="sorry">';
        foreach (
    $error_message as $key => $value
          {
            echo 
    "$value'<br />';
          }
        }
        echo 
    '</p>';
      }
    ?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <fieldset>
    <legend>Feedback Form</legend>
    <div class="row">
    <span class="formLabel"><label for="fullname">Full Name*</label><br /></span>
    <input class="inputfield" type="text" id="fullname" name="fullname" size="30" value="<?php echo (isset($_POST['fullname'])) ? htmlentities($_POST['fullname']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formLabel"><label for="tel">Telephone*</label><br /></span>
    <input class="inputfield" type="text" id="tel" name="tel" size="30" value="<?php echo (isset($_POST['tel'])) ? htmlentities($_POST['tel']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formLabel"><label for="email">Email Address</label><br /></span>
    <input class="inputfield" type="text" id="email" name="email" size="30" value="<?php echo (isset($_POST['email'])) ? htmlentities($_POST['email']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formMessage">Message<br /></span>
    <textarea class="inputarea" name="message" rows="5" cols="30"><?php echo (isset($_POST['message'])) ? htmlentities($_POST['message']) : ""?></textarea>
    </div>
    </fieldset>
    <p><input type="submit" class="inputsend" name="SUBMIT" value="Send Form" /></p>
    </form>

    </body>
    </html>
    I changed some details, so take a good look at the code.

    I'm sure this can be improved, but hopefully it'll help a bit.

  10. #10
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Will have a good look through and compare, Thank you much appreciated - I'm still a bit of a PHP newbie - lots to learn

    Out of curiosity is there any way to test it, to emulate what the Hijaking actually does.

    Not sure where the reference to an sql query came from either??

    Thanks again guys

  11. #11
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    There is a way to test it, yes. Read this article http://securephp.damonkohler.com/ind...mail_Injection a couple off times, it'll give you a better understanding of the problem.
    There have been and are a lot of threads about the injection problem. I gave some more info and links here.

    The difficult part is to choose which function to use, there are many possibilities. It all depends on how you want to stop the spammers. So far I prefer the function I gave in this thread. Anything which looks like an attempt will stop the script. It's also possible to strip out the "bad" data, and still send the email, but I don't like that solution because then you still receive the bogus emails.

    The function isInjection returns true or false. When true, there's an injection attempt. After that you can do anything you want. Send a friendly or not so friendly error message back, or send yourself a warning email.

  12. #12
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,933
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by PixelPyro
    Okay I have added the code as above (both options as recommended) just want to confirm that I have them in the correct places.

    PHP Code:
    <?php
    if (!preg_match('/^[a-zA-Z\._\-0-9]+?@[a-zA-Z\._\-0-9]+?\.[a-zA-Z\._\-0-9]{2,3}$/',$_POST['email'])) die('Invalid email format');

    if((
    $_POST['fullname'] == '') || ($_POST['tel'] == '')) {
    $error '<strong>Sorry</strong>, You seem to have missed out some required fields:';
    if(
    $_POST['fullname'] == '') {
    $error_fullname ' <br /><strong>Full Name</strong> is a required Field';
    }
    if(
    $_POST['tel'] == ''){
    $error_tel ' <br /><strong>Telephone</strong> is a required Field';
    }
    }
    The above in my opinion is, well pretty crap. First it kills the script if there is a syntax error in the email address. Why not reload the form? It was probably a typo anyway. Second it just checks if fields are empty and not that they contain what they are supposed to. Third, function isInjection($text) is unnecessary if you check your input as in point two above. in fact it is a distraction as you are looking for one type of attack instead of checking input properly. Fourth, $error_message[] = "Email injection attempt!"; any information such as this is extremely helpful to someone trying to undermine a script. Either kill the script, send a 404 or ban them.

  13. #13
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Bokehman is absolutely right. The script I gave works, but there's a lot to improve. (was very late at night when I posted that. Maybe shouldn't post a script at all if not properly done.... sorry about that). Killing the script after a syntax error in the email is not good..

    So indeed, do some research on ways to validate different forms of data. Numbers, emailadresses, length of input, etc etc. And then return nice error messages and let people correct their mistakes.

    About the email injection function: I use it as an extra, even if it is redundant. I guess it depends on the way the whole script is set up and which other validation measures you're taking, and which values end up in the headers of the email. The best approach is to use a whitelist for values you want.

    You could also check out existing solutions. There are some pretty good form validation classes out there (see phpclasses.org for example), which are very easy to use.

  14. #14
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cheers for the article will have a look through that.

    Quote Originally Posted by matthijsA
    The difficult part is to choose which function to use, there are many possibilities. It all depends on how you want to stop the spammers. So far I prefer the function I gave in this thread. Anything which looks like an attempt will stop the script. It's also possible to strip out the "bad" data, and still send the email, but I don't like that solution because then you still receive the bogus emails.
    Basically I want to stop the spammers dead - I imagine that it is all automated and so am not particullary concerned about giving error messages that will never be seen or recieving emails that notify of an attempt.

    Quote Originally Posted by bokehman
    The above in my opinion is, well pretty crap. First it kills the script if there is a syntax error in the email address. Why not reload the form? It was probably a typo anyway. Second it just checks if fields are empty and not that they contain what they are supposed to. Third, function isInjection($text) is unnecessary if you check your input as in point two above. in fact it is a distraction as you are looking for one type of attack instead of checking input properly. Fourth, $error_message[] = "Email injection attempt!"; any information such as this is extremely helpful to someone trying to undermine a script. Either kill the script, send a 404 or ban them.
    Thanks for the feedback bokehman - are you saying the solution above won't work that that it isn't the "best solution". As far as I can tell most things can have multiple solutions that address the original issues, some better then others, I would be imterested in knowing what you would do in this case to from Hijaking

    thanks again all

    edited - will look at the phpclasses.org site

  15. #15
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    PixelPyro,
    An article I found helpfull was http://www.devshed.com/c/a/PHP/Build...lidator-Class/

    It gave a good idea how such a class can be set up.

    On the phpclasses site there are some good classes. See for the top rated:
    http://www.phpclasses.org/browse/cla...top/rated.html
    A very comprehensive class is the one from Manuel Lamos:
    http://www.phpclasses.org/browse/package/1.html
    Some smaller and maybe easier to comprehend are:
    http://www.phpclasses.org/browse/package/1982.html from Olaf Lederer.
    or
    http://www.phpclasses.org/browse/package/1164.html

    The nice thing about using a class is that it is easily reusable and it makes your code leaner and easier to read through.

    Please post again if you have any questions. There's some good help here.
    I'm also interested in the solution Bokehman would use.

  16. #16
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice one - quick question, although not the "best solution" the one you have provide is a viable one that I can use temporarally to knock all this on the head untill I can take sometime to review the above links/articles - is that correct. Basically want to stop attempts and relieve the grief from clients recieving half a dozen emails of "wierd" (clients term) emails on a semi regular basis.


    cheers

  17. #17
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,933
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by PixelPyro
    are you saying the solution above won't work
    I am not saying that. The solution above works for and only for a particular type of attack. If the input is supposed to be red, do a test for red. Don't do a test to make sure it's not blue.

  18. #18
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Yes, that function does work. I use it on a couple of sites and so far it has blocked hundreds of attempts, while allowing valid data to go through. Maybe you could change the error message "Email injection attempt" to something more general like "There seems to be a problem with the data you entered. Please try again or contact us via 123-3456....".
    Giving away any information a hacker could use is indeed not good, as Bokehman suggested. However, I think that in case someone enters invalid data by accident, for example "Hi, I sent you a bcc: but you didn't respond..." it's better to give them a nice error message then a 404 page.

  19. #19
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,933
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by matthijsA
    it's better to give them a nice error message then a 404 page.
    Give them a nice error message if you think they are a nice person but if you believe you are receiving hacker input I would send a 404 to all future requests from that user. It might even please them if they think they have crashed the site.

  20. #20
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by PixelPyro
    are you saying the solution above won't work
    I am not saying that. The solution above works for and only for a particular type of attack. It's a bit like putting your wallet in your right hand pocket because you know there is a pickpocket that only steals from peoples left pockets.
    That's correct. I guess what bokehman is pointing us to is to use a whitelist approach instead of a blacklist approach. Only let through data you want, nothing else. Otherwise, you keep adding more to your blacklist. (am I understanding correct bokehman?)

    However, in this case I think it's ok to (also) filter for the values about which you know can be used for injection attempts (bcc: , multipart, etc). If those are allowed to pass through your other validation rules, you'll still be vulnerable.

    A book I'm reading at the moment is Essential PHP Security from Chris Shiflett. There's some good info there. Also check out his website (shiflett.org) for more background information and articles.

  21. #21
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understand what you are saying in terms of a whitelist/blacklist, seems to make alot of sense considering how spammers/hackers/etc will devise new and imporved techniques on a weekly basis it seems.

    I will look into all the suggestions and thanks again, one and all.

  22. #22
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Guys

    Apologies for this, I have uploaded the page to test and found that any html above the form itself is removed from the page - if however I fill in the form either correctly or not and recieve the error/thank you message then the rest of the page is displayed. Clearly it is something to do with the

    PHP Code:
    <?php 
    if (isset($sent)) 
      { 
      echo 
    '<p><span class="thanks"><strong>Thank you</strong> for contacting Tablets of Stone.</span></p>'
      } 



    if (isset(
    $error_message)) 
      { 
        echo 
    '<p class="sorry">'
        foreach (
    $error_message as $key => $value
          { 
            echo 
    "$value'<br />'
          } 
        } 
        echo 
    '</p>'
      } 
    ?>
    portion of the code stripping out anything before it, but I can't work it out. Help please.

  23. #23
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    There was a } missing in the code I posted here. Sorry about that.
    PHP Code:
    <?php
    // function by Andrew Krespanis
    function isInjection($text) {
          
    $text strtolower($text);
          if (
    preg_match('#(content\s*-\s*disposition)|(bcc\:)|(cc\:)|(content\s*-\s*transfer\s*-\s*encoding)|(mime\s*-\s*version)|(multipart\s*/\s*mixed)|(multipart\s*/\s*alternative)|(multipart\s*/\s*related)|(reply\s*-\s*to)|(x\s*-\s*mailer)|(x\s*-\s*sender)|(x\s*-\s*uidl)#is',$text))
          { return 
    true; }
          else
          { return 
    false;}
    }
    // declare an empty error array
    $error_message = array();

    // if form submitted
    if (isset($_POST['SUBMIT']))
    {
        if (
    get_magic_quotes_gpc()) 
            {
          foreach (
    $_POST as $key => $value)
            {
            
    $temp stripslashes($value);
            
    $_POST[$key] = $temp;
            }
            }

        
    // function by praetor
        
    if (!preg_match('/^[a-zA-Z\._\-0-9]+?@[a-zA-Z\._\-0-9]+?\.[a-zA-Z\._\-0-9]{2,3}$/',$_POST['email']))
        {
          
    $error_message[] = 'Invalid email!';
        }

        if((
    $_POST['fullname'] == '') || ($_POST['tel'] == ''))
        {
           
    $error_message[] = '<strong>Sorry</strong>, You seem to have missed out some required fields:';
        }
      
        if(
    $_POST['fullname'] == '')
        {
          
    $error_message[] = ' <br /><strong>Full Name</strong> is a required Field';
        }
      
        if(
    $_POST['tel'] == '')
        {
          
    $error_message[] = ' <br /><strong>Telephone</strong> is a required Field';
        }
      
        
    // is there any email injection attempt?
        
    if( isInjection($_POST['fullname']) || isInjection($_POST['tel']) || isInjection($_POST['email']) || isInjection($_POST['message'])) {
           
    $error_message[]  = "There seems to be a problem with the data you entered, please try again.";
        }

        
    // if there are no errors continue
        
    if(count($error_message) ==0)
        {
         
    // proceed to mail()
        
    $to 'info@mydomian.co.ukk';
        
    $subject 'Website form';
        
    // message goes here
        
    $message "Full Name: " $_POST['fullname'] . "\n";
        
    $message .= "Telephone: " $_POST['tel'] . "\n";
        
    $message .= "Email: " $_POST['email'] . "\n";
        
    $message .= "Message: " $_POST['message'] . "\n";

        
    // headers go here
        
    $headers "From: " $_POST['email'] . "\n";
        
    $headers .= "Content-type: text/plain; charset=UTF-8";
        
    $sent mail($to$subject$message$headers);
        
    //$autorespond = mail($_POST['email'], "Form Auto Response.", "Thank you for contacting Me, your message has been received and we will contact you shortly.", "From: info@mydomian.co.ukk<info@mydomian.co.ukk>");
        
        
    }
    }
    ?>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">

    <head>
    <title></title>
    </head>
    <body>
    <p>test</p>
    <?php
    if (isset($sent))
      {
      echo 
    '<p><span class="thanks"><strong>Thank you</strong> for contacting Tablets of Stone.</span></p>';
      }



    if (isset(
    $error_message))
      {
        echo 
    '<p class="sorry">';
        foreach (
    $error_message as $key => $value)
          {
            echo 
    "$value'<br />';
          }
        
        echo 
    '</p>';
      }
    ?>

    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <fieldset>
    <legend>Feedback Form</legend>
    <div class="row">
    <span class="formLabel"><label for="fullname">Full Name*</label><br /></span>
    <input class="inputfield" type="text" id="fullname" name="fullname" size="30" value="<?php echo (isset($_POST['fullname'])) ? htmlentities($_POST['fullname']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formLabel"><label for="tel">Telephone*</label><br /></span>
    <input class="inputfield" type="text" id="tel" name="tel" size="30" value="<?php echo (isset($_POST['tel'])) ? htmlentities($_POST['tel']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formLabel"><label for="email">Email Address</label><br /></span>
    <input class="inputfield" type="text" id="email" name="email" size="30" value="<?php echo (isset($_POST['email'])) ? htmlentities($_POST['email']) : ""?>"/>
    </div>
    <div class="row">
    <span class="formMessage">Message<br /></span>
    <textarea class="inputarea" name="message" rows="5" cols="30"><?php echo (isset($_POST['message'])) ? htmlentities($_POST['message']) : ""?></textarea>
    </div>
    </fieldset>
    <p><input type="submit" class="inputsend" name="SUBMIT" value="Send Form" /></p>
    </form>

    </body>
    </html>

  24. #24
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    London UK
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thats great thanks again matthijsA - I did have a look through (should have spotted that) - all in working order

    cheers


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •