Php 如何使用验证码正确保护表单

Php 如何使用验证码正确保护表单,php,curl,Php,Curl,我正在维护其他人开发的一些页面。我注意到,表单是由某种图像验证码保护的,每次用户进入页面时都会生成这种图像验证码。验证码存储在名为check的隐藏输入中,用户输入的值与提交表单后隐藏输入的值进行比较 我曾尝试使用cURL从隐藏的输入中读取page和CAPTHA $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "http://example.com/form/"); curl_setopt($curl, CURLOPT_

我正在维护其他人开发的一些页面。我注意到,表单是由某种图像验证码保护的,每次用户进入页面时都会生成这种图像验证码。验证码存储在名为
check
的隐藏输入中,用户输入的值与提交表单后隐藏输入的值进行比较

我曾尝试使用cURL从隐藏的输入中读取page和CAPTHA

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://example.com/form/");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($curl);

$html = str_get_html($result);
$captcha = $html->find('input[name=check]');
var_dump($captcha[0]->value);

curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
    "name"      => "Joe",
    "telephone" => "1423456789",
    "message"   => "Lorem ipsum",
    "auth"      => $captcha[0]->value,
    "check"     => $captcha[0]->value,
    "submit_f1" => "Send"
));

$result = curl_exec($curl);
curl_close ($curl);
运行上述脚本将导致正确的表单提交。此外,我注意到,我可以简单地覆盖post数组中的
auth
check
值:

    "auth"      => 123,
    "check"     => 123,
并且表单也被正确提交


我意识到没有100%安全的方法来保护表单,但我如何才能保护我的表单多一点,并使自动提交变得更难。

任何质询响应系统背后的想法是,您将响应(代码)隐藏起来,而只显示质询(图像)

您通常会使用会话来完成此任务;您将响应存储在会话中并显示质询。输入正确的响应后,您可以清除response session变量,以使系统为下一个质询做好准备

下面的代码只是用来说明这个想法

显示验证码 验证验证码
正如其他人所说,使用
$\u会话
是实现这一点最常见的方法

  • 生成一个随机字符串并将其存储在
    $\u会话中
  • 将该随机字符串绘制到jpg并将其保存在tmp文件夹中
  • 在表单旁边向用户显示jpg
  • 将输入与会话值进行比较
  • 但是,如果会话的使用对您不可用,另一种(稍微不常见的)方法是使用散列

  • 生成一个随机字符串
    $ranstr
  • 计算
    SHA256($ranstr.$SECRET)
    其中
    $SECRET
    是一个长的服务器端机密值,您应该偶尔更改它
  • $ranstr
    绘制到jpg并将其保存在tmp文件夹中
  • 在表单旁边向用户显示jpg。表单还将在隐藏字段中包含哈希结果
  • 重新计算SHA256($POST['human_test'.$SECRET),并将其与隐藏字段的值进行比较

  • 在这两种情况下,最好添加一个cron来删除超过1小时左右的JPG。

    如果您可以编辑代码,我建议您使用
    google recaptcha
    session_start();
    
    // generate the string you wish to show as captcha
    $str = generate_captcha();
    // and store inside session
    $_SESSION['captcha'] = $str;
    
    // show_captcha() would generate the image
    echo show_captcha($str);
    
    session_start();
    
    if ($_POST['captcha'] === $_SESSION['captcha']) {
        unset($_SESSION['captcha']);
        // continue with form submission
    } else {
        // yikes, it doesn't match
    }