This question already has answers here:
How to Prevent SPAM without CAPTCHAs or a Centrally managed system (e.g. akismet)
(10 answers)
Closed 9 years ago.
I have a simple form that users use to register their email address for a newsletter.
I want to prevent spammers submitting 000's of fake emails. What's the best way to do this?
I thought about limiting the number of inputs from each IP address to, say, 60 per hour, but then thought anyone determined will simply spoof their IP as part of the attack.
Any ideas?
*EDIT: I am looking for a server-side solution. In this situation, UX is important so I don't want to use a captcha, or ask the user to validate with a token
You could use negative captcha. Idea is to have a field in the form that is not visible to humans but bots would enter values in it. On server side you can ignore requests that have a value in the negative captcha field.
Adavatage is that normal users do not see any extra steps like enter captcha words or validate the email. Cons is that the method works as long as people would not customize bots specifically for your site.
Example of a negative captcha. Include this in your form.
<div style="position: absolute; left:-2000px;"><input type="text" name="email_name" value="" /></div>
On server side do somethig like
if (params[:email_name] != "") //bot
else //not a bot
I found a great technique somewhere on the interwebs. I enhanced it, and it is now available (open source) at www.formspammertrap.com .
It uses some javascript to replace the form action, and requires actual 'clickage' of a live user.
No captchas, hidden fields, etc.; those might work temporarily, but usually doesn't work long-term.
It is free, and it works great on any site I put it on. PHP-based, but will also work in WordPress (not a plugin).
You could do something like this,
function validEmail($email){
if (filter_var($email, FILTER_VALIDATE_EMAIL)){
list($user,$domain) = explode('#',$email);
return checkdnsrr($domain, 'MX');
}
return false;
}
it may not pick up every fake email, but I always validate their email by sending them a validation email with a link.
EDIT:
As for spam on a form use CSRF, that should prevent most spam (at least in my experience)
When a user types their email address into the bar, run a script that sends them an email to the address specified that contains a link, when they click the link it will activate that email address for newsletters.
You could use capthcha - which is broken and annoying to users.
What I use is a simple question (how many logs does a dog have) and then use the input of <input type='text' name='email2' value=''>. I then do the necessary checks on the server-side of things. But one thing I do not do is to notify the person that something was wrong i.e. invalid number entered in the email2 textbox.
Anyway, just a thought.
A common approach is, to add another textfield to the form-section. In your stylesheet (not the style-tag!), you set its css-property to display:none, since most spambots fillout every available input-element, but doesn’t load external .css-files.
When your script gets the request, you check this hidden textfield – if it’s blank, you have good chances that this wasn’t spam.
Related
I have a holiday website I built years ago in ColdFusion. I'm not the best programmer so I enlisted the help of a senior programmer to do the "heavy lifting." Unfortunately, he is not available at this time.
QUESTION:
On the site, there is a form for kids to email Santa. In an effort to get them to come back, I send them a "Secret Passcode" they can use to come back to the site the next day to get Santa's response (Santa is super busy this time of year and can't respond instantly - more realistic.) I collect their email, first name and "wish list" info and stuff it into a DB.
The problem I'm having is that a reasonable percentage of kids/parents mistype their email address (e.g. suzy#gmial.com vs suzy#gmail.com) causing them to never get their "Secret Passcode" or hear back from the North Pole at all! This, of course, could be challenging for Santa believers wondering why Santa never got back to them.
Is there a way to do a real time check to see if the email address is valid BEFORE entering it into the DB, and toss up a response page stating "The email address you entered is not valid. Please check that you spelled it correctly" or something similar.
~ North Pole Needs Your Help.
Have you tried using mailcheck? It's a Javascript library and jQuery plugin that suggests a right domain when your users misspell it in an email address. The developers of the script claim it has reduced their sign up confirmation email bounces by 50%. There are instructions available for jQuery & non-jQuery usage.
https://github.com/mailcheck/mailcheck
Check out the live demo here (and enter "suzy#gmial.com").
http://kicksend.com/join
You'll need to perform server-side validation using ColdFusion before you use CFMail or the user will get a visible error. Use isvalid("email", Form.Email) to determine if the address is valid.
And now it's up to me to disappoint Santa? Oh, my...
It is not possible.
You cannot check for typos. Example? Your example: gmial.com is valid.
You can do a rough check one of more characters followed by an # sign followed by two or more characters followed by a dot followed by two or more characters There are a lot of regular expression to be found online, just ask Google for "regular expression email javascript". Please choose a simple one.
The only thing is hoping that the email-sending process is fast and add a line or two to ask them to check their email and if there is nothing in it in a minute or two they have to check if their email is correct. You may have the password-input on the same page they send you their data, to raise the chance they keep that page open.
I am trying to learn as much as possible about running a high-profile website. I designing some user registration screens and was thinking about the typical CAPTCHA, or annoying alternatives. In my opinion, having them either causes accessibility issues, or simply bothers potential customers and inhibits their registration process.
My question is whether spambots recognize and trigger JavaScript events, such as the keydown or keypress event on an input field. From what I can gather, most bots simply do form posts via the action attribute and don't programmatically "fill out" web forms.
In theory, I could add JavaScript that something like the following:
<input name="email" />
<input name="human" type="hidden" />
<script>
var emailField = document.getElementById( 'email' );
emailField.onkeydown = function( ) {
document.getElementById( 'human' ).value = "human";
};
</script>
Then, on the server side, I could verify that the post data includes a value of "human" for the hidden form field.
Is this a viable solution, at least as effective as typing in a bunch of random, difficult-to-read characters? Would using a random generated value from the server be more helpful in repetitive attempts than a static value of "human"?
Most spam bots will simply look for a <form> on your page and then post data directly to the URL specified in the action attribute. This is very simple, lightweight, and easy to do.
Some spam bots will actually use a headless browser (such as PhantomJS) which executes JavaScript on the page. These spam bots are much harder to fool, but few bots use this method since it is much more expensive (in CPU and RAM).
I've found that it's generally fine to go for blocking the most common spam bots through a honeypot (field on the page that is removed programmatically, and other similar methods). Some bots will get through, and anyone who does manual analysis to find a way to exploit your page will still get in. For most sites, this is good enough, and provides a good balance in preventing spam while keeping your site usable.
I want to use JavaScript to detect if a webpage has a login form or not in order to autofill the user's credential. I'm thinking of checking if there is an input with id="username"/"id",
however each website will have its own naming convention. What is the proper way to implement this?
I think the best way is to search for an input of type password. They are used only almost solely for logins. But you will also need to distinguish between login and signup forms. One way of doing it is counting the number of password inputs. Most signups have 2 password inputs to confirm. But this is less sure. You will probably need more filters. Maybe also try to find the words "signup" or "login" enclosed in the form tag, or immediately preceding it.
There is no one sure way. You'll have to use your ingenuity.
I also had to undergo the same scenario. I used following criteria to detect whether login panel exists or not.
By checking whether type="submit" (if login panel exists, in most cases form should be there to submit the data) and type="password" (password need to exists in order to capture the password typing in hidden manner).
But still there is no proper way. You need to come up with your filters.
I've got a site where users extend their product trial with a registration code. They click a link (with a key in the URL) from an email, get to this site and a lightbox appears with their registration code. I'm currently displaying the registration code with HTML and hiding it with CSS. Once I check to make sure the URL has the correct key with javascript, I display the registration code. However, this means anyone can just view source on the page and copy the registration code. Is there a way to encrypt the code so it doesn't appear in view source, and then decrypt it if the URL has the correct key? It's one code per product, not per user, so I don't have to do any server side authentication.
If the computer knows it, the user knows it.
You can play obfuscation games, all of which amount to making your Javascript hard to read. But a sufficiently determined user will find it anyway, and once they do, they can easily share it with their friends.
One code per user is the only way to fix this reliably.
I check to make sure the URL has the correct key with javascript
Don't check the key client-side, validate the key on the server.
This is the only way to ensure only valid users get the registration code.
Pseudo PHP example:
if( validateKey($_GET['key']) ) {
echo 'The Registration Code';
} else {
echo 'Error';
}
Client Side Code is inherently insecure. Consider anything you send to a client machine public to the world, and don't trust anything that comes from the client until you cleanse it. A sufficiently determined user will de-obfuscate your code, regardless how much effort you put into the initial obfuscation routine.
Another tip to help you instead to show the registration code in the site you can send back an email to the user with the registration code.
And as Nemo suggest, the right way is one code for user
Hope it help
As mentioned before the client side will not cover your security needs.
Better would be to have the page send a Ajax request to the server containing the key, you can then respond with the registration code.
Even better would be to directly validate the key on the first request, then decide to return an error page or the page with the registration info.
As others have replied, doing this validation server-side is both easier and more secure.
You can have an AJAX request posting the URL key to a php page, that in turn would reply with the correct registration code.
That being said, there is always the possibility of using a client-side use encryption library (like AES), but from what i understand i don't think it would be a good approach to solving your problem.
Again, doing it on the server-side is both extremely easy and as secure as you need.
Encrypt your registration code (plus some magic cookie) with the key in the server before embedding it in your HTML. In your JavaScript, validate the key (which comes in the URL) by decrypting the registration code. If the magic cookie matches, then you get a valid key and you can display the registration code to the user.
View Source will only reveal the encrypted registration code. Without the key, the snooper has no way to extract the registration code.
This means that you'll have a unique key per registration code, which should be the case for your registration system. The key you send to the user in an email, embedded into a link which they click as you said.
I want to add a simple Contact form to my web site so that customers can contact me easily.
<form>
NAME
<input type='text' name='name' />
EMAIL
<input type='text' name='email' />
MESSAGE
<textarea name='message' />
<input type='submit' />
</form>
This form would simply email me the customers message.
But, I also want to reduce (not, I'm not saying eliminate but at least reduce), SPAM.
I've looked into using CAPTCHAs but, ultimately, I don't want to hinder the customer with having to fill out extra information.
Any ideas of a good simple spam prevention/reduction method I could use for my Contact form.
A very simple trick I've been using with a surprisingly good success rate is this: Provide a text field that is hidden from human users with style="display: none", but with an enticing name like email. Most bots will fill in something in this field, but humans can't see it so they wont. At the server, just make sure the field is empty, else treat the submission as spam.
If you want to do a completely front-end solution I have had success recently by leaving the form action attribute blank, and populating it via a $(document).ready function. Most spambots use a browser that has javascript disabled, or are looking for hidden fields to avoid detection.
Example:
Your html would be:
<form method="POST" action="" id="contact-form">
and anywhere in that page you can use this to populate it.
<script>
$(document).ready(function(){
$("#contact-form").attr("action", "/yourMailScript.cgi");
});
</script>
A bot browser with no javascript will not get a form action, and they will get a 404 upon submission. Anyone with a normal browser (unless they have JS disabled for paranoid reasons) will get the normal behavior.
The only (client-side) way other than a CAPTCHA type user confirmation would be to write the whole thing dynamically. A lot (but not all) of robots would probably ignore the dynamic content. Eg
document.write("<"+"form>"
+" NAME "
+" <"+"input type='text' name='name' /> "
+"EMAIL "
+"<"+"input type='text' name='email' /> "
+"MESSAGE "
+"<"+"textarea name='message' /> "
+"<"+"input type='submit' /> "
+"<\/form> ");
Use Google or Yahoo mail account. They have good anti-SPAM filters.
Hidden fields, silly questions (what is 3+4?), etc, are not very effective at blocking spam on forms, IMHO.
I researched this several years ago, and came up with a solution I call "FormSpammerTrap". It uses JavaScript code to 'watch' for focus/onclick on required fields. Automated processes, unless highly customized for a specific site (which takes more time than spambot owners want to take), can't 'focus/onclick' a required field. (And there are some other techniques I use.)
I have a free solution at my www.FormSpammerTrap.com site. And there's a form there that spambots can try to spam...and they haven't, for more than 3 years. You are welcome to try it out...it's all open source, so you can see how it works. (And, if you use the form, I don't harvest your email. I reply once, then delete your email.)
My technique is much more effective in blocking spambots, IMHO. They haven't been able to spambot the contact form on that site.
**Added 12 Jul 2018 **
The trick is to add an on-click/on-focus event that changes the action parameter to the actual processing page. Otherwise, the default value I use is a honeytrap-type site. I think it's hard for a spammer to simulate those events, although possible perhaps. The technique blocks a lot of bot-spammers.
And still, after a couple of years using the technique on that site, the form hasn't been spammed by bots. (I define a bot spammer that sends multiple submits via the attack, not just one submit.)
Works for me.
You can add simple question, each serious person who wants to contact you, can easily answer. For example a field where he should enter the first letter of the domain. Most bots don't understand the question and will enter nothing or something random.
You could also try to track the time how long the user needs to input data. If he tries to send the form earlier than 5 seconds before typing the first word just don't allow to send it. Bots usually just parse the site, fill out everything and then post it and go to the next website.
#sec {
visibility: hidden;
padding: 0;
margin: 0;
height: 1;
}
<form method="POST" action="www.google.com">
NAME
<input type='text' name='name' />
<br /> EMAIL
<input type='text' name='email' />
<br /> MESSAGE
<textarea name='message' /></textarea>
<br />
<input type='text' name='security' id='sec' placeholder="Do not enter anything here" />
<input type='submit' formaction="" />
</form>
**Here, only a user who clicks on the submit button actually could submit the form. using auto submit simply redirects the bot to google.com.
**
*Also the input 'security' is an input field that is hidden to users, and visible to certain bots, known commonly as HoneyPot Captcha. On the server side, you can simply skip all the requests that has the 'security' field filled. Not every bot can be tricked this way, and this is where the attribute formaction comes into play *
grep for URI methods, urlencoded characters, or the two HTML markup characters, seems to work.
Use an anti-spam API like Akismet or Cleantalk. You can use the traditional checks for less sophisticated bots before hitting the API. An anti-spam API is the only way to catch spam submitted by a human.
I think that nowadays, most of the solutions posted are either inefficient or outdated.
reCAPTCHA is not a hassle for users any more
google documentation
reCAPTCHA v3 returns a score for each request without user friction.
The score is based on interactions with your site and enables you to
take an appropriate action for your site.
OP states that he needs an alternative to CAPTCHA, in order to avoid hassle for his users (up to v.2, reCAPTCHA requires user interaction). However, as of v.3, reCAPTCHA can detect bots "silently", without requiring user interaction.
Front-end-only solutions are inefficient
The honeypot (hidden input that only a bot could fill) and simple questions methods, as well as other front-end implementations, are still vulnerable to spam attacks. First of all, the spammer can bypass all front-end and post directly to the server. Therefore, a server-side check is required.
In addition, if someone wants to spam your site, specifically, he can easily read your source-code and build a script that is "clever" enough to not be caught by the front-end protection.
On the other side, reCAPTCHA v.3 tracks data and works behind the scenes, in Google's back-end, to determine if the user is actually human. Its logic is hidden, therefore, the attacker can not easily develop a "smarter" bot. In addition, the attacker can not just bypass the front-end; a token is created, is passed server-side and then to Google's back-end to be validated.
TL;DR
Nowadays, reCAPTCHA seems to be the best solution in all aspects. No user friction and the most secure.
Use JS technology. Like if a user comes on your contact page then javascript will generate a string or anything like that you prefer and put the information on a hidden text field. But it is not the actual solution, smart bot can easily crack it.
Another way is, You can also use email verification after contact form submission. And store the data on your database. If customer verifies the url through email then the contact information will mailed to you from database.
And also use delay to prevent continuous robot attack. Like sleep() in PHP code. This will add few delay in your code. By this way you can reduce random attacks but this is not the prevention method.
I found a nice idea on this page:
http://www.evengrounds.com/developers/alternatives-to-captcha
You can make your SUBMIT button display a confirmation page, on which you explain to user that he has to hit CONFIRM button to actually send a message. Spambots would usually only submit first form and skip the second step.
If you dont want to use recaptcha then you can use a service like Real Email and validate the emails server side before processing. Keep in mind that your probably want a way to report to the user if there is something wrong with the input.