Author Topic: Secure Forms [Spam]  (Read 4184 times)

0 Members and 1 Guest are viewing this topic.

Offline ki0be

  • /dev/null
  • *
  • Posts: 10
  • Cookies: 5
  • www.ki0be.com
    • View Profile
    • Kiobe's Space
Secure Forms [Spam]
« on: January 04, 2013, 09:58:06 am »
Well, I work at a Web Solutions company and our server has been sending out a lot of spam and we're getting a lot of requests from chinese web servers.  This has lead me to believe that our contact forms are being injected.  I've written some PHP that will only allow the email to be sent if certain conditions are met - here is the code.

(form-check.php - include) Generates random key, saves it in session variable. 
Code: [Select]
<?php
session_start
();
function 
generateKybit ($length 40){
    
$bitkey "";
    
$possible '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"£$%^&*()';
    
$maxlength strlen($possible);
    
    if (
$length $maxlength) {
        
$length $maxlength;
    }
    
$i 0;
    
    while (
$i $length) {
        
$char substr($possiblemt_rand(0$maxlength-1), 1);
        if (!
strstr($bitkey$char)) {
            
$bitkey .=$char;
            
$i++;
        }
    }
    return 
md5($bitkey);
}
$_SESSION['kybit'] = generateKybit();
?>

(do-send.php - action of form | post)

Code: [Select]
<?php
session_start
();
$sendto "info@you.com";
$details = array(htmlentities($_POST['name']),$_POST['email'],htmlentities($_POST['phone']));
$message "A person has tried to contact you via your website.\nName: " $details[0] . "\nNumber: " $details[2] . "\nEmail: " $details[1];
if (isset(
$_SESSION['kybit'])){
    
} else {
    
$_SESSION['kybit'] = rand(540);
}
$kybit['client'] = $_SESSION['kybit'];
$kybit['server'] = $_GET['ky'];
if (
$kybit['client'] == $kybit['server']){
    if(!
filter_var($details[1], FILTER_VALIDATE_EMAIL))
    {
    exit(
"<div style='font-family:Arial;background-color:#FF7A7A;border:solid 5px #C90000;padding:20px;width:170px;margin:0 auto;'><p><strong>E-mail is not valid.<br/> <a href='index.php'> &laquo; Go Back</a></strong></p>");
    }
    
mail($sendto,'Website Enqiry'$message);
    
$_SESSION['kybit'] = rand(540);
        echo 
"<div style='font-family:Arial;background-color:#A6FFA7;border:solid 5px #007A02;padding:20px;width:170px;margin:0 auto;'><p><strong>Email Sent!</strong><br/> <a href='index.php'> &laquo; Go Back</a></strong></p>";
} else {
    echo 
"<div style='font-family:Arial;background-color:#FF7A7A;border:solid 5px #C90000;padding:20px;width:170px;margin:0 auto;'><p><strong>Invalid Security Token</strong></p>";
}
?>


If the md5 attached via GET matches the md5 sent via POST then the e-mail sends.  If not, it returns an error and does not send the e-mail.  The keys are unique and can only be used once.

Have I wasted my time doing this and if so, is there a quicker alternative to securing forms?  I have considered implementing captcha fields into my forms, but with just shy of 1,000 customers - it's a bit too much hassle (playing with public/private keys, etc.)


Offline aichi

  • /dev/null
  • *
  • Posts: 8
  • Cookies: 2
  • aichi ninja
    • View Profile
    • aichi-ninja's github
Re: Secure Forms [Spam]
« Reply #1 on: March 11, 2013, 07:02:05 am »
just use google recaptcha, it's free and super easy to use.
-- silence is not a virtue
http://aichi-ninja.blogspot.com/

Offline wookie

  • Peasant
  • *
  • Posts: 68
  • Cookies: -4
    • View Profile
Re: Secure Forms [Spam]
« Reply #2 on: March 11, 2013, 08:57:53 am »
just use google recaptcha, it's free and super easy to use.


And ridiculously hard to read most of the time.


Try going down the route of having a stupid "Are you human? (type Yes)" thing and see if that resolves it, otherwise you're on the right track with the hash, try something like this;


Code: [Select]
<?php
$randString 
"^&*&DF43lk#][;/.,";
$user="myName";
$pin=rand();
$date=date('YmdH');
$hash=sha1("$date|$user|$pin|$randString");


// url should be mydomain.com/contact.php?user=myName&pin=$pinOutput&hash=$hashOutput
?>



Then at the post end, decipher it;

Code: [Select]
<?php
$randString 
"^&*&DF43lk#][;/.,";
$user=$_GET['user'];
$pin=$_GET['pin'];
$date=date('YmdH');
$myHash=sha1("$date|$user|$pin|$randString");
if(
$myHash == $_GET['hash']){
// doSend();
}else{
die(
"Sorry, this contact form has expired, please try again.");
}
?>



You could also do some timing things, like putting a <input type="hidden" name="start" value="<? microtime(true); ?>" /> in the form and at the backend working out how long it's taken for them to complete the form, because if it's a bot doing it it's likely to be quite quick.

Hope this helps.