开发者

How to create simple javascript/jquery client side captcha?

开发者 https://www.devze.com 2023-01-06 19:24 出处:网络
How to create simple javascript/jquery c开发者_开发技巧lient side captcha? Why don\'t you use reCAPTCHA ? It\'s free, very efficient, and provides accessibility functionnalities.It can be done with HT

How to create simple javascript/jquery c开发者_开发技巧lient side captcha?


Why don't you use reCAPTCHA ? It's free, very efficient, and provides accessibility functionnalities.


It can be done with HTML and a simple JavaScript code. Have a look at this:

 function Captcha(){
     var alpha = new Array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
	 	'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 
 	    	'0','1','2','3','4','5','6','7','8','9');
     var i;
     for (i=0;i<6;i++){
         var a = alpha[Math.floor(Math.random() * alpha.length)];
         var b = alpha[Math.floor(Math.random() * alpha.length)];
         var c = alpha[Math.floor(Math.random() * alpha.length)];
         var d = alpha[Math.floor(Math.random() * alpha.length)];
         var e = alpha[Math.floor(Math.random() * alpha.length)];
         var f = alpha[Math.floor(Math.random() * alpha.length)];
         var g = alpha[Math.floor(Math.random() * alpha.length)];
                      }
         var code = a + ' ' + b + ' ' + ' ' + c + ' ' + d + ' ' + e + ' '+ f + ' ' + g;
         document.getElementById("mainCaptcha").innerHTML = code
		 document.getElementById("mainCaptcha").value = code
       }
function ValidCaptcha(){
     var string1 = removeSpaces(document.getElementById('mainCaptcha').value);
     var string2 =         removeSpaces(document.getElementById('txtInput').value);
     if (string1 == string2){
            return true;
     }else{        
          return false;
          }
}
function removeSpaces(string){
     return string.split(' ').join('');
}
.capt{
	background-color:grey;
	width: 300px;
	height:100px;
	
}

#mainCaptcha{
	position: relative;
	left : 60px;
	top: 5px;
	
}

#refresh{
	position:relative;
	left:230px;
	width:30px;
	height:30px;
	bottom:45px;
	background-image: url(rpt.jpg);
}

#txtInput, #Button1{
	position: relative;
	left:40px;
	bottom: 40px;
}
<link rel="stylesheet" type="text/css" href="estilo.css" />
<script type="text/javascript" src="script.js"></script>    
<body onload="Captcha();"> 
   <div class="capt"> 
   <h2 type="text" id="mainCaptcha"></h2>
   <p><input type="button" id="refresh" onclick="Captcha();"/></p>            <input type="text" id="txtInput"/>    
   <input id="Button1" type="button" value="Check" onclick="alert(ValidCaptcha());"/>
   </div>
</body>


here you are ;)

var captchaText;
$(function() {
  var pre = $('#captcha');
  captchaText = pre.text();
  pre.text('');

  var lines = ['', '', '', '', '']
  for (var ixLetter = 0; ixLetter < captchaText.length; ixLetter++) {
    var letter = captchaText.substr(ixLetter, 1);

    var letterLines = letters[letter];
    for (var ix = 0; ix < 5; ix++) {
      lines[ix] = lines[ix] + '  ' + letterLines[ix];
    }
  }
  for (var ix = 0; ix < 5; ix++) {
    pre.append(lines[ix] + '\n');
  }
});

function check() {
  if ($('#captchaCheck').val() == captchaText) {
    alert('you are probably human');
  } else {
    alert('you probably made a mistake. Don\'t worry. To err is also human.');
  }
}
var letters = {
  h: [
    'HH  HH',
    'HH  HH',
    'HHHHHH',
    'HH  HH',
    'HH  HH'
  ],
  i: [
    'II',
    'II',
    'II',
    'II',
    'II'
  ]
  // etc
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<pre id="captcha">hi</pre> Please type what you see: <input id="captchaCheck" /> <input type="button" value="Check" onclick="check()" />


I agree with all the comments that client side captcha is fundamentally flawed, and I don't know know tough the hurdles have to be to mitigate any amount of spam...

To get an impression of what you're up against, though, check xRumer and GSA in action: YouTube: xEvil vs GSA Captcha Breaker

The software is also able to gather and decipher artificial intelligence such as security questions (i.e. what is 2+2?) often used by forums upon registration. Since the latest version of XRumer, the software is capable of collecting such security questions from multiple sources and is much more effective in defeating them.

wikipedia.org/wiki/XRumer

References:

  • How do spambots work? - Webmasters Stack Exchange (2010!)
  • BotDetect: Pure JavaScript CAPTCHA Validation Problems

So, caveats aside, here's a trivial alternative using HTML5 validation that's probably as ineffective as the other posts here! Presumably spambots would just add formnovalidate before submission, and would identify a honeypot field.

<form class="input">
  <label for="number" class="title">
    What is three plus four?
  </label>
  <br>
  <input 
    name="number" 
    required="required"
    pattern="(7|seven)" 
    oninvalid="this.setCustomValidity('Sorry, please enter the correct answer')"
    oninput="this.setCustomValidity('')"
  >
  
  <!-- Bonus honeypot field, hidden from the user.  The server should discard this response if it contains any input -->
  <input name="decoy" style="display: none;" />

  <input type="submit">
</form>


Client-Side captchas do not provide the protection a server-generated captcha would because the server can not check if the solved captcha is solved correctly.


That is not possible.

You could create something that looks like a CAPTCHA, but it would only run when it's not needed, i.e. when the page is shown in a browser. When it's needed it won't run, as the program trying to break in won't run the client side script.


 function Captcha(){
     var alpha = new Array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 
            '0','1','2','3','4','5','6','7','8','9');
     var i;
     for (i=0;i<6;i++){
         var a = alpha[Math.floor(Math.random() * alpha.length)];
         var b = alpha[Math.floor(Math.random() * alpha.length)];
         var c = alpha[Math.floor(Math.random() * alpha.length)];
         var d = alpha[Math.floor(Math.random() * alpha.length)];
         var e = alpha[Math.floor(Math.random() * alpha.length)];
         var f = alpha[Math.floor(Math.random() * alpha.length)];
         var g = alpha[Math.floor(Math.random() * alpha.length)];
                      }
         var code = a + ' ' + b + ' ' + ' ' + c + ' ' + d + ' ' + e + ' '+ f + ' ' + g;
         document.getElementById("mainCaptcha").innerHTML = code
         document.getElementById("mainCaptcha").value = code
       }
function ValidCaptcha(){
     var string1 = removeSpaces(document.getElementById('mainCaptcha').value);
     var string2 =         removeSpaces(document.getElementById('txtInput').value);
     if (string1 == string2){
            return true;
     }else{        
          return false;
          }
}
function removeSpaces(string){
     return string.split(' ').join('');
}
<h1 This works pretty well. </h1>


if your purpose is to simply deflect most bots, you might be able to get away with a simple script that chooses 2 numbers at random and asks user to add them.


Try this:

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
/* created dynamically by server when preparing the page */
// f function is on server and not known by bot and is random per result 
// maybe bcrypt with a unique salt per request
var encodedResult = "f('X')"; 
var serverRenderedPositionSequence = [
    [0,0],
    [10,10],
    [20,20],
    [30,30],
    [40,40],
    [50,50],
    [60,60],
    [70,70],
    [80,80],
    [90,90],
    [100,100],
    [100,100],
    [100,100],
    [100,100],
    [100,100],
    [100,0],
    [90,10],
    [80,20],
    [70,30],
    [60,40],
    [50,50],
    [40,60],
    [30,70],
    [20,80],
    [10,90],
    [0,100]
];

window.index = 0;

window.move=function(but){
      but.style.left = (serverRenderedPositionSequence[window.index][0]+"px");
      but.style.top = (serverRenderedPositionSequence[window.index][1]+"px");
      window.index++;
      if(window.index<serverRenderedPositionSequence.length)
      {
          setTimeout(function(){
              window.move(but);
          },125);
      }
}
window.onload=function(){
  var but = document.getElementById("decoy-button");
  window.index=0;
  window.move(but);
};
function post()
{
  // do something with
  var xhrData= {
    encodedResult:encodedResult, 
    result:document.getElementById('result').value
  };
  var postXhr=function(){ /* HTTP POST */}
  
  // server checks if decoded "encoded result" is equal to the result (X here)
  postXhr(xhrData);
}
</script>
</head>
<body>
    <input id="result" type="text" value="Enter the message you see" />
    <input id="test" onclick="post()" type="button" value="Post" />
   
    <input id="decoy-button" type="button" value="   click me bot" style="width:0px;padding:0;position:absolute; left:0px; top:0px;" />
    <input id="secret" type="button" onclick="window.index=0;move( document.getElementById('decoy-button'))" value="repeat sequence" />
</body>
</html>

Then the server would only use bcrypt to check if result is true.

Since the pattern matching requires dynamically observing the screen, it would cause some bots to fail. These would fail:

  • bots that click to post button immediately
  • bots that don't run javascript
  • bots that mis-click the decoy buttons
  • bots that can't understand the leap between coordinates in the sequence
    • for example when drawing X, it leaps from bot-right to top-right effectively drawing a vertical line on imaginary plane which may trick some bots easily
  • bots that use OCR with "fixed" screenshot timings

To further obfuscate any "canvas" hack, the server could add quick random bursts (with decreased latency between leaps) into the sequence such that resulting image would look unrecognizable but human will see what it writes between those random bursts.

To add one more depth, you can ask a math problem like

1+1

instead of just string.

But, when a bot memoizes the encoded result and re-sends it, the security is broken. So, have a "session" for client and not send any encoded result. Just the randomized sequence and check for result only by server-side. Of course the session also costs database time/space but at least website admin/editor does not see spam on the control panel of website.


please try this

<script type="text/javascript">
    $('#submitcapt').click(function(){
        var captval = "This will not do nothing";
        $.ajax({
            type : "POST",
            url : "externals/reCaptcha/ajaxaction.php",
            data : {loadval:captval},
            success : function( msg ) {
                if(msg=="1"){

                }else{

                }
            }
        })
    });
</script>

In ajaxaction.php please put the following code

<?php
    session_start();
    $val=$_POST['loadval'];
    $message= $_SESSION['random_number'];
    if($val==$message) {
        echo "1";
    }else{
        echo "2";
    }
?> 


$(document).ready(function() {
    DrawCaptcha();
});

function refreshCap() {
    DrawCaptcha();
}

function DrawCaptcha() {
    var a = Math.ceil(Math.random() * 10) + '';
    var b = Math.ceil(Math.random() * 10) + '';
    var c = Math.ceil(Math.random() * 10) + '';
    var d = Math.ceil(Math.random() * 10) + '';
    var e = Math.ceil(Math.random() * 10) + '';
    var f = Math.ceil(Math.random() * 10) + '';
    var g = Math.ceil(Math.random() * 10) + '';
    var code = a + ' ' + b + ' ' + ' ' + c + ' ' + d + ' ' + e + ' ' + f + ' ' + g;
    var test = document.getElementById("ContentPlaceHolder1_txtCapcha").value = code;
    alert(test);
}

function ValidCaptcha() {
    var str1 = removeSpaces(document.getElementById('ContentPlaceHolder1_txtCapcha').value);
    var str2 = removeSpaces(document.getElementById('ContentPlaceHolder1_txtinputCapcha').value);
    if (str1 != str2) {
        alert("Properly enter the Security code.");
        document.getElementById('ContentPlaceHolder1_txtinputCapcha').focus() return false;
    }
}

function removeSpaces(string) {
    return string.split(' ').join('');
}
0

精彩评论

暂无评论...
验证码 换一张
取 消