How to protect a contact form without captcha?

做~自己de王妃 提交于 2020-01-22 10:23:05

问题


On my website I have a couple of forms where someone (without registration) can send message to specified, registered user. The form is simple, and I want to keep that way. What is the best way to protect a contact form againts spam and bots if I don't want to use any captcha?

Your message:...
Your e-mail:...
[Send]

回答1:


So the options:

  1. Maximize query/IP
  2. Add security question
  3. Captcha (even if you don't like it)
  4. Sending e-mail to validate it
  5. Submitting data via JavaScript

Details on these and my opinion on them.

  1. It works well to prevent sending many messages, but a few copies of them will still get in. If you think that's affordable, this might work. Note: a spammer can use proxies or dinamic IP, but that might be slow. Perhaps consider not blocking the user but adding a captcha if they send too many e-mails.
  2. What is this exactly? These are questions like "10+1" or "ten plus 1" or "What day is it?". They might work well - if your website will be in only very few languages. Captchas are still better but this works well in case.
  3. You don't like it, but I still say it's the best. Adding one reCAPTCHA isn't that hard but it will prevent 90% of the spammers - or more. But there are 2 problems with this: 1. sometimes human can't read it as well, 2. spammers could use people to solve it for a minimal (like $0.001/captcha) amount and sometimes they do. But that stands for case 2 as well.
  4. Could be good, but if spammers note this, they can generate random email addresses and validate it via SMTP. But they usually go to the easiest target and leave.
  5. Good, spammers can't make bots act like a click, but they can make codes which makes click non-required. But the easiest target rule stays.

In my opinion, the best is solution 3, then solution 2, then solution 1, then solution 4 and 5.




回答2:


You can protect your form with the form keys technique:

  1. When displaying the form to the user, generate a random ID ("form key") just for this single form submission. Store the form key in a session variable. Submit the "form key" in a hidden input field.
  2. On the submit side, check the submitted form key against the one stored in the session variable. Immediately invalidate it after use. (delete it from the session)

Without a captcha or something comparable, it is impossible to really protect a form from abuse.

However, using this technique a malicious spammer would have to

  1. request for form via HTTP for each single form submission to obtain a valid unique forkey
  2. parse the DOM tree / HTML code to obtain the form key
  3. submit it in the correct format

No automatic spamming contact form crawler does that, as far as i know.

This technique also protects your form from multiple accidential submissions.

Here is a code example:

<?php
session_start();
if (isset($_POST['form_submit'])) {
  // do stuff
  if (isset($_POST['formkey']) && isset($_SESSION['formkeys'][$_POST['formkey']])) {
    echo "valid, doing stuff now ... "; flush();
    // delete formkey from session
    unset($_SESSION['formkeys'][$_POST['formkey']]);
    // release session early - after committing the session data is read-only
    session_write_close();
    // do whatever you like with the form data here
    send_contact_mail($_POST);
  }
  else {
    echo "request invalid or timed out.";
  }
}
else {
  // show form with formkey
  $formkey = md5("foo".microtime().rand(1,999999));
  // put current formkey into list of valid form keys for the user session
  if (!is_array($_SESSION['formkeys']) {
    $_SESSION['formkeys'] = array();
  ]
  $_SESSION['formkeys'][$formkey] = now();
?>
<html>
<head><title>form key</title></head>
<body>
  <form method="POST">
    <input type="hidden" name="PHPSESSID" value="<?=session_id()?>">
    <input type="text" name="formkey" 
      value="<?= $formkey ?>">
    <input type="submit" name="form_submit" value="Contact us!">
  </form>
</body>
</html>
<?php } ?>



回答3:


In my opinion, many sites (excepting ticket sellers, major sites like google, and other sites that will be targeted) can prevent comment/form spam without a captcha by using a number of different techniques in combination. I recently created an open source PHP project that implements the following tests to determine if the submission is likely legitimate, or spam.

  • Hidden Form Field - If hidden form field is filled in, this is an indicator of spam
  • Time Form Submission - If form is filled out too fast or too slow, this is an indicator of spam
  • Too many URLs - If the comment field has too many URLs (Number is configurable) this is an indicator of spam
  • Mouse Movement - If the user does not use their mouse, this is an indicator of spam
  • Used Keyboard - If the user does not use their keyboard, this is an indicator of spam
  • Validate Referer - If the HTTP referer does not match the form URL, we shouldn't accept the submission.
  • Validate Email - If the email address provided in the form is not valid from a syntax perspective, we shouldn't accept the submission.

Here is the URL of the project. I like Kaii's test above, would make a great additional test for phpFormProtect. https://github.com/mccarthy/phpFormProtect




回答4:


You can implement a time limit from an IP. So if a spam bot tries to send the form again and again (in a specific time interval, say 1 hour), the request should be rejected.

You'll have to do this on the Server-Side by checking and storing the IPs of the users. Then when they again send the form, check if the user is already in the blocked IPs for the time being.

This is also what StackOverflow implemented 2years back.




回答5:


You can do something to prove the user is human. If you want to keep simple, maybe a field asking a math question, like "2 + 5?", for example. But that's not so secure as a captcha could be. But, if the possible spam doesn't botter you, it's ok to do that.



来源:https://stackoverflow.com/questions/9516540/how-to-protect-a-contact-form-without-captcha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!