Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spam responses from website contact form bypassing 'required' and 'pattern' attributes

I have a contact form on a website that has been receiving a lot of spam. It is hosting on Github so my methods of server side validation / captcha is quite limited. All fields always had the 'required' attribute and I have added some 'pattern' attributes to the form field and a very basic security question.

Originally I would receive spam responses with all fields completed but random numbers where the name should be, a name where the phone number should be, an email, and URLs in the message area.

When I first added just the security question handled by javascript / jquery, it seems to have no effect so I am assuming the bot could read the correct answer from the code?? What is more concerning, is that after more recently adding some 'pattern' attribute to the form fields I have started getting spam responses that still contain random numbers where the name should be, and now the phone and email field is non existent (not submitted / entered).

I do not get how the field can be submitted when it doesnt match the pattern validation, or how two fields can be left blank when they still have the 'required' attribute. I have tested the form myself and all validation and required fields function as expected and all fields are received like they used to be so it is just the spammer that seems to ignore these rules.

If anyone can please explain what may be happening / have happened here?? Also / alternatively if anyone is aware of a better and proven way of weeding out spam responses that works with the form I have and within the constraints of hosting the website on Github that would be GREATLY appreciated!!

The website in question is http://orionimportgroup.com/ if you would like to see the form in the live environment.

var n1 = Math.round(Math.random() * 10 + 1);
var n2 = Math.round(Math.random() * 10 + 1);

$('document').ready(function(){
	$("#a").val(n1 + " + " + n2);
	document.getElementsByName('captcha')[0].placeholder=("CAPTCHA CODE: " + n1 + "+" + n2);
});

$('form').submit(function(e) {
	if (eval($("#captcha").val()) == (parseInt(n1) + parseInt(n2))) {
		e.preventDefault();
		$.ajax({
			url: "https://docs.google.com/a/blakedavies.net/forms/d/e/1FAIpQLSfHdHMJePTJ3R5JOtBrH8zdPdX74eXQ8TDFIGjgkbIbGNdpnQ/formResponse",
			data: $(this).serialize(),
			type: "POST",
			dataType: "xml",
			success: function(data) {
				console.log('Submission successful');
			},
			error: function(xhr, status, error) {
				console.log('Submission failed: ' + error);
			}
		});
		$('#gform *').fadeOut(0);
		$('#contact-box *').fadeOut(0);
		$('#gform').prepend(
			'<div class="thank-you-box"><p class="thank-you">Hi, thanks for reaching out! We will get back to you within 24 hours.</p><p class="thank-you">If your issue cannot wait, you can also reach us via our <a href="https://www.facebook.com/Orion-Import-Group-110501569627947/">Facebook Page</a> or call 0429-105-580.</p></div>'
		);
		return true;
	}
	else{
		alert('You have not entered the correct captcha code value');
		return false;
	}
});
<form name="gform" id="gform" enctype="text/plain" action="https://docs.google.com/a/blakedavies.net/forms/d/e/1FAIpQLSfHdHMJePTJ3R5JOtBrH8zdPdX74eXQ8TDFIGjgkbIbGNdpnQ/formResponse">
  <div class="inner">
	  <input name="entry.1683926249" id="entry.1683926249" placeholder="Name" required pattern="[A-Za-z' -]+" oninvalid="setCustomValidity('Please enter a valid name using letters only.')" onchange="try{setCustomValidity('')}catch(e){}" />
		<input name="entry.189066148" id="entry.189066148" placeholder="Phone" required pattern="[0-9 -]+" oninvalid="setCustomValidity('Please enter a valid phone number using numbers only.')" onchange="try{setCustomValidity('')}catch(e){}" />
		<input name="entry.429019481" id="entry.429019481" placeholder="Email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$" oninvalid="setCustomValidity('Please enter a valid email making sure to include an @ sign and the domain suffix (.com .net etc.).')" onchange="try{setCustomValidity('')}catch(e){}" />
	</div>
	<div class="inner">
		<textarea name="entry.2094840737" id="entry.2094840737" placeholder="Message" required></textarea>
		<input name="captcha" id="captcha" placeholder="CAPTCHA CODE: 5+7" required />
	</div>
  <input class="submit" name="submit" type="submit" value="Send Message" />
</form>
<script src="js/contactform.js" type="text/javascript"></script>
like image 284
user7531422 Avatar asked Mar 02 '18 17:03

user7531422


People also ask

Why do spam bots fill out forms?

A bot will normally fill in that field (they usually fill in all fields to avoid possible required-field validation errors) but a user would not, since it's hidden. So on POST you check for a value in that field and SILENTLY fail to send the message if there is a value in it.


1 Answers

One way to prevent spam is Honeypot technique, it is proven to work and prevented more than 90% of spam for my company's site.

To implement the Honeypot technique, all that’s required is adding a hidden form field to the form.

And that’s what gives away whether the form submission is spam or not:
Real users don’t see the hidden field so they won’t submit it with any value.
Spam bots, however, will still see the field in the form’s markup, auto-populate it with something, and submit it with the rest of the form.

So from there all that’s needed is to test whether the hidden field was submitted with a value or not. If it was, the submission can be treated as spam.

Read more about Honeypot technique

Response to comments and additional info (I can't comment yet)

@user7531422, try it like this:
Add a class to an additional input element (honeypot element) with CSS style to hide it display: none;, and make it look same as the name or phone field but change name attribute.
most bots will read only the HTML markup and won't notice CSS rules, and most bots aren't so smart to dive into every piece of code.

Before submitting the form directly check if your hidden field has data (Check for it value if not empty), if so don't even send the form.
It's a client side solution.

like image 64
Basel Issmail Avatar answered Sep 30 '22 04:09

Basel Issmail