Greetings,

I have a site that was created back when the dinosaours were around and of course there is a feedback form that wasn't secure and was generating spam via injections. I have implemented my typical measures; CAPTCHA, preg_match, trim, stripslashes, strip_tags, and even preg_replace. Still the spam continues.

I have implemented the creation of a txt file to log each submit of the form with the idea of seeing what exactly is being injected to cause this.

The problem is nothing is apparent in the log. The only obvious indication is that a drop down form field right after the email field is blank in the log which would be impossible if the form was being used the correct way.

Here is the code to generate the log, this is placed before any modification to the post data.

    $myFile = "spamlog/";
    $myFile .= $DateTime;
    $myFile .= ".txt";  

    $fh = fopen($myFile, 'w') or die("can't open file");
    $stringData = "Visitor Field Entry<br><br>";
    $stringData .= "Subject: ".$_POST['txttitle']."<br>";
    $stringData .= "Name: ".$_POST['txtname']."<br>";
    $stringData .= "Email: ".$_POST['txtemail']."<br>";
    $stringData .= "Country: ".$_POST['txtcountry']."<br>";
    $stringData .= "Comments: ".$_POST['txtcomments']."<br><br>";
    $stringData .= "Visitor IP: ".$_SERVER["REMOTE_ADDR"];

    fwrite($fh, $stringData);
    fclose($fh);
    chmod($myFile, 0777);

I guess what I am tried to ask is; How can you properly echo POST data as they were entered, special characters and all? I want to see EVERYTHING that is being entered into the form.

Thanks

Recommended Answers

All 26 Replies

I assume all you want to do is ignore these attempts to spam your form. Since you know (evidence a blank or missing entry in your $_POST array) then server validation could (should) ignore or return an error (depending on the submission / validation method) and discard the submission.
Presumably the spammer is submitting directly to your website using values scraped from your form without using your form.
CSRF suggested by diafol would be useful in the case where you couldn't tell from the posted data that it wasn't generated by your form.

Thanks for the responses. @diafol: The IP's from the attacks lastnight 96.47.224.50 and 173.44.37.234 which come from IPTELLIGENT. My research shows they are useless when it comes to abuse reports. I have not used a CSRF token, but there is already a CAPTCHA in place which lead me to believe these spam injections are attended form submisions.

@nauticalmac What I would really like to do is see exactly what is being entered into the fields. Iwan't to know exactly how 'they' are doing this.

Here is one of the logs...

Visitor Field Entry

Subject: zieyvct mgdvtpd
Name: Pay day loans canada
Email: mixpsqydqi@vrssdf.com
Country: 
Comments: eilbanbjofnbuft, <a href="http://pariswells.com.au/">Levitra blindness</a>, cJkfpfI, [url=http://pariswells.com.au/]Levitra prescribing[/url], HWPQIoX, http://pariswells.com.au/ Levitra, mAJjdHU, <a href="http://peterberley.com/classes/">Ambien next day delivery</a>, yrUNqBv, [url=http://peterberley.com/classes/]Ambien[/url], JoDmLvG, http://peterberley.com/classes/ Cheap ambien, ebaYlHC, <a href="http://bestenhancer.ca/">Hydromax Pump</a>, DZpcsJs, [url=http://bestenhancer.ca/]Bath Mate[/url], iTPniRt, http://bestenhancer.ca/ Hydromax, walLMsO, <a href="http://clarkstreetssa.org/">Payday Loans</a>, sKbVbPQ, [url=http://clarkstreetssa.org/]Apollo pay day loans[/url], pgAZwmB, http://clarkstreetssa.org/ Payday Loans, COBAOmE, <a href="http://www.viagracomments.com/">Achalasia sildenafil</a>, lnydHfD, [url=http://www.viagracomments.com/]Generic sildenafil[/url], svUxgmX, http://www.viagracomments.com/ Does generic viagra contain less sildenafil citrate , LtrIzCa, <a href="http://www.newramic.com/">Casinos en ligne</a>, EBefcJw, [url=http://www.newramic.com/]Casino canada en ligne[/url], gmBZkxu, http://www.newramic.com/ Casino en ligne au canada, AkbpCHt.

Visitor IP: 173.44.37.234

Note that the 'Country' is blank. This is a drop down field with no blank options.

I could just reject the form if ANY fields are blank including counrty, but I really would like to know how they are getting by the security that is in place so that I know for future projects.

What exactly do you mean by '...via injections'. Why do you think there is different data entered from the data in the $_POST variable. Are you sure the CAPTCHA is implemented correctly? Maybe you could share your validation code. Without seeing that, I can't tell what in the example above (apart from the CAPTCHA) should have prevented a submission from a different form.

Member Avatar for diafol

Indeed, a look at your markup and supporting php for the form would be helpful

First off strict validation of datatype ($string,$email)
It just so happens I wrote a simple class for that

// my validate function
class Myvalidatefns{
function validate($var){
    return is_string($var) && ctype_alpha($var);

}
function validEmail($email){
    return filter_var($email, FILTER_VALIDATE_EMAIL);

}
function validIntfields($int){
    return filter_var($int,FILTER_VALIDATE_INT);
}
function isValid($var){
    if($this->validate($var)){
    null;
}else{
    echo "Only alphabetical characters are allowed in this field. "."<br/>";
}
}
function isValidemail($var){
    if($this->validEmail($var)){
        null;
    }else{
        echo "The email address you entered is invalid."."<br/>";
    }
}
function isValidint($var){
    if($this->validIntfields($var)){
        null;

    }else{
        echo "Only numbers are accepted in this field";
    }
}
}

Validate the post array.
Secondly escaping input is usually not necessary but because you're not interested in special characters escape your user input with

htmlspecialchars(); 

Its better than these functions

preg_match, trim, stripslashes, strip_tags.

Last but not least if you are saving your data in the database , use PDO prepared statements and bind parameters PDO
Good luck!

I'm interested in the CAPTCA validation, there's no mention of it in your log, sabyre.

The missing form data (dropdown) leads me to believe that something other than what is showing in the log is 'injected' in the email field.

What exactly do you mean by '...via injections'. Why do you think there is different data entered from the data in the $_POST variable.

The processor:

if ( $cmd == 'posted' ){

    //-- Set Time Offset
    $TOffset = 3;

    $TIME = mktime(date("H")+$TOffset,date("i"),date("s"),date("m"), date("d"),date("Y"));
    $DateTime = date("YmdHis",$TIME);
    //$Date = date("Ymd",$TIME);

    $myFile = "spamlog/";
    $myFile .= $DateTime;
    $myFile .= ".txt";  

    $fh = fopen($myFile, 'w') or die("can't open file");
    $stringData = "Visitor Field Entry<br><br>";
    $stringData .= "Subject: ".$_POST['txttitle']."<br>";
    $stringData .= "Name: ".$_POST['txtname']."<br>";
    $stringData .= "Email: ".$_POST['txtemail']."<br>";
    $stringData .= "Country: ".$_POST['txtcountry']."<br>";
    $stringData .= "Comments: ".$_POST['txtcomments']."<br><br>";
    $stringData .= "Visitor IP: ".$_SERVER["REMOTE_ADDR"];

    if (!$_POST['txtcountry']) {
        $stringData .= "<BR><BR>BLANK";
    }

    fwrite($fh, $stringData);
    fclose($fh);
    chmod($myFile, 0777);

    $txttitle = stripslashes(strip_tags(trim($_POST['txttitle'])));
    $txtname = stripslashes(strip_tags(trim($_POST['txtname'])));
    $txtemail = stripslashes(strip_tags(trim($_POST['txtemail'])));
    $txtcountry = stripslashes(strip_tags(trim($_POST['txtcountry'])));
    $txtcomments = stripslashes(strip_tags(trim($_POST['txtcomments'])));


    //$txtemail = preg_replace("([rn])", "", $txtemail);
    $find = "/(content-type|bcc:|cc:)/i";
    if (preg_match($find, $txtname) || preg_match($find, $txtemail) || preg_match($find, $txttitle) || preg_match($find, $txtcomments)) {
        echo "<h1>Error</h1>n
        <p>No meta/header injections, please.</p>";
        exit;
    }


    $t->assign('txttitle', $txttitle);
    $t->assign('txtname', $txtname);
    $t->assign('txtemail', $txtemail);
    $t->assign('txtcountry', $txtcountry);
    $t->assign('txtcomments', $txtcomments);

    if (strtolower($_SESSION['spam_code']) != strtolower($_POST['spam_code'])) {
        $t->assign('msg', '121');
    } else {

        $From    = $config['admin_email'];
        $To      = $config['feedback_email'];
        $Subject = get_lang('email_feedback_subject');

        $message = get_lang('feedback_email_to_admin', MAIL_FORMAT);
        $message = str_replace('#txttitle#',$txttitle,$message);
        $message = str_replace('#txtname#', $txtname,$message);
        $message = str_replace('#txtemail#',$txtemail,$message);
        $message = str_replace('#txtcountry#', $lang['countries'][$txtcountry],$message);
        $message = str_replace('#txtcomments#', $txtcomments, $message);

        $message2 = "<br><br>Spam control: http://mainemates.com/".$myFile;


        $success= mailSender($From, $To, $To, $Subject, $message.$message2);

        $t->assign( 'success', $success );
    }
} else if ($_SESSION['UserId'] > 0) {
    $t->assign('txtname', $_SESSION['FullName']);
    $t->assign('txtemail', $_SESSION['email']);
}

The captcha is a simple session var match. I assumed the captcha matched else processing would simply not continue.

    if (strtolower($_SESSION['spam_code']) != strtolower($_POST['spam_code'])) {
        $t->assign('msg', '121');
    } else {

Like I said, I am really curious about what 'they' are doing to make this happen.
Please feel free to test the form and see if you can get past security.

Thanks everyone for your feedback.

Made several attempts. The CAPTCHA seems to be working. If not a manual submission, they must have found a way round it. Try adding the 'spam_code' to the log.
Sorry I can't come up with anything better.

Thank you for trying ... I'll add both $_SESSION['spam_code'] and $_POST['spam_code'] to the log and report back.

Hot off the presses.....

CAPTCHA (Session): || CAPTCHA (Field):

Log shows blanks.... explain that one.

Member Avatar for diafol

Place this in a local file and see if it has the same effect:

<form name="frmContact" action="...url..." method="post">
        <input type="hidden" name="cmd" value="posted" />
        Subject:
        <input type="text" name="txttitle" value="" size="30" maxlength="30"/>
        Name:
        <input type="text" name="txtname" value="" size="20" maxlength="20" />
        Email:
        <input type="text" name="txtemail" value="" size="30" maxlength="150"  />
        Country:
        <select name="txtcountry" id="txtcountry">
            <option label="United States" value="US" selected="selected">United States</option>
        </select>
        Comments:
        <textarea rows="10" cols="55" name="txtcomments"></textarea>
        <input type="text" size="10" name="spam_code" id="spam_code" value="" />
        <img src="...url...spam_image.php" alt="Code" />
        <input name="submit" class="formbutton" type="submit" value="Submit"/>
        <input name="reset" type="reset" value="Reset" class="formbutton"/>
    </form>

Perhaps you could leave out the spam fields

I don't think I understand.... I can't spot a difference. Will this allow me to see exactly what is being inserted?

After your suggestions and looing into it a bit more it seems I could easily do something to stop the submissions....

Example:

if (!$_SESSION['spam_code']) {
    echo "We don't like your kind around here, get lost!";
    exit();
}

What I want to know is how do I find out exatly what they are submitting that is making the country drop down var come back empty and now that I know, how are they making the session captcha blank?

Thanks

Member Avatar for diafol
<form name="frmContact" action="...url.../feedback.php" method="post">
    <input type="hidden" name="cmd" value="posted" />
    Subject:
    <input type="text" name="txttitle" value="" size="30" maxlength="30"/>
    Name:
    <input type="text" name="txtname" value="" size="20" maxlength="20" />
    Email:
    <input type="text" name="txtemail" value="" size="30" maxlength="150"  />
    Comments:
    <textarea rows="10" cols="55" name="txtcomments"></textarea>
    <input name="submit" class="formbutton" type="submit" value="Submit"/>
    <input name="reset" type="reset" value="Reset" class="formbutton"/>
</form>

OK, well try that without the fields as I suggested.

I tried that during my 'attack' but received the 'invalid code' message.
It looks like at least you can stop them (it would be easy for them to fill the country code. By the way this only has one option for me (US). Ther may be something different going on with that input.

@diafol

Place this in a local file and see if it has the same effect:

Do you mean basically try to submit the form outside of the server?

Is it possible they are injecting a javascript function to a POST field? Still wouldn't explain why I can't echo the POST VAR as they entered it... well maybe it does... Perhaps they are injecting a " followed by javascript declairing the rest of the POST VARS skipping the country?

Member Avatar for diafol

Have you tried what I suggested? I.e. submitting the form from outside the server, as you put it.

I'm not saying that this is the way it was done, but you need to see if form spoofing could be used.

Any combos could be used...

<form name="frmContact" action="...url.../feedback.php" method="post">
    <input type="hidden" name="cmd" value="posted" />
    Subject:
    <input type="text" name="txttitle" value="" size="30" maxlength="30"/>
    Name:
    <input type="text" name="txtname" value="" size="20" maxlength="20" />
    Email:
    <input type="text" name="txtemail" value="" size="30" maxlength="150"  />
    Country:
    <!-- NOTE THE CHANGE FOR COUNTRY -->
    <input name="txtcountry" id="txtcountry" value="" />
    Comments:
    <textarea rows="10" cols="55" name="txtcomments"></textarea>
    <input type="text" size="10" name="spam_code" id="spam_code" value="" />
    <img src="...url.../spam_image.php" alt="Code" />
    <input name="submit" class="formbutton" type="submit" value="Submit"/>
    <input name="reset" type="reset" value="Reset" class="formbutton"/>
</form>

XSS however, is another aspect that you should look to prevent

I will give that a shot and report back with my findings.

Bug 420025 - contentDocument not populated after pageshow event

XSS me is bugged or at least with the current mozilla or the form and my attempt(S) at being a bad guy fails. I tried injection and externally submitting nothing got past security. I'll just lock it down and call it good.

Thank you everyone for your feedback and assistance.

Would it be possible to remove the domain refference from these posts?

Member Avatar for diafol

Erm, that's quite a few posts I think. Why do you need to do that?

Just 4, 3 of yours and 1 of mine on the first page. Just wanted to keep it away from spiders. No worries if it's too much to ask. Thanks again.

Member Avatar for diafol

OK, removed - no effect on the readability for others.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.