【问题标题】:How to properly secure form with CAPTCHA如何使用 CAPTCHA 正确保护表单
【发布时间】:2012-09-25 09:52:13
【问题描述】:

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

我尝试使用 cURL 从隐藏的输入中读取页面和 parse 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);

运行上述脚本会导致正确的表单提交。更重要的是,我注意到,我可以简单地覆盖后数组中的 authcheck 值:

    "auth"      => 123,
    "check"     => 123,

并且表单也被正确提交。

我意识到没有 100% 安全的方法来保护表单,但是我怎样才能更多地保护我的表单并让自动提交变得更难一些。

【问题讨论】:

  • 如果您可以编辑代码,我建议您使用google recaptcha

标签: php curl


【解决方案1】:

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

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

以下代码仅用于说明这个想法。

显示验证码

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
}

【讨论】:

    【解决方案2】:

    正如其他人所说,使用$_SESSION 是完成此任务的最常用方法;

    1. 生成一个随机字符串并将其存储在$_SESSION中。
    2. 将该随机字符串绘制为 jpg 并将其保存在 tmp 文件夹中。
    3. 在表单旁边向用户显示 jpg。
    4. 将输入与会话值进行比较。

    但是,如果您无法使用会话,另一种(不太常见的)方法是使用哈希;

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

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

    【讨论】:

      猜你喜欢
      • 2021-01-26
      • 1970-01-01
      • 2012-12-11
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多