【问题标题】:Preventing traffic from circumventing a landing page [closed]防止流量绕过着陆页[关闭]
【发布时间】:2017-03-31 08:40:44
【问题描述】:

我有一个网站,当访问者登陆多个登录页面(不同语言)中的任何一个时,他们有机会将多个促销代码中的任何一个输入到表单中。如果他们输入了一个正确的代码(存储在 SQL 表中),他们会转到带有表单的另一个页面,在那里他们可以提供邮寄信息以接收免费产品。如果他们输入的代码不在桌面上,他们会收到一条消息,表明他们输入的代码无效并被阻止。

这通过 php 工作。当登录页面表单被输入并提交时,会生成一个类似这样的 URL:website.com/formentry.php?promo=code,其中“code”与用户在表单中输入的任何内容相匹配。如果“代码”与数据库表中代码列中的字符串匹配,它们将被发送到输入表单。如果不匹配,它们将被阻止。至此,一切正常,并且已经顺利运行了几个月。

但是最近发现了一个问题:可以通过在浏览器的 URL 字段中直接输入 website.com/formentry.php?code=code 来绕过登录页面。这是一个问题有几个原因,我需要防止它成为可能。

有人对解决方案有任何想法吗?也许使用 .htaccess 文件将这些 URL 请求发送回登录页面?

【问题讨论】:

    标签: php html mysql .htaccess http-redirect


    【解决方案1】:

    使用会话,您可以设置用户在登录页面上输入正确代码时的会话:

    session_start();
    $_SESSION[valid_user] = true;
    

    然后,在每个其他页面(非登陆页面)上,放置一个验证器,例如:

    if (!$_SESSION[valid_user])
    {
      echo "You do not have permission to view this page";
    }
    

    或者,您可以将用户重定向到另一个页面,而不是显示错误消息:

    if (!$_SESSION[valid_user])
    {
      $url = "http://example.com";
      header("Location: $url");
      exit();
    }
    

    如果您想更进一步,让我们说一下身份验证。 code是420,可以设置登陆页取提交的code并设置

    $_SESSION[420] = true;

    并在产品#420 或其他页面上验证用户会话是否包含420 == true。这样,如果他们使用优惠券代码 420,他们只能查看产品 #420 的页面,而不是所有产品页面。

    【讨论】:

    • 感谢您的详细帮助,@jacey!但是,我已尽我所能按照您的指示进行操作,但有些东西不起作用。我添加了 $_SESSION[valid_user] = true;到登陆页面,并且 if (!$_SESSION[valid_user]) { echo "您没有权限查看此页面"; } 到条目表单页面,即使我正确地通过登录页面进入条目页面,也会出现回显消息。代码中是否有某些东西否定了 $_SESSION 的真实价值?
    • 如果我理解正确,您当前在着陆页上的程序会检查代码是否有效。使用相同的代码来设置会话。我不知道您的着陆页代码现在做什么,但可能类似于“如果代码有效,则将用户带到正确的页面”。将您的代码稍微更改为“如果代码有效,请设置 SESSION 变量,然后将用户带到正确的页面”。如果代码无效,请不要设置会话变量。
    • 嗨,Jacey,看起来它不起作用,因为我没有包含 session_start();在宣布会话之前。一旦我在两个页面的顶部添加了那行代码,您的解决方案就可以工作了!谢谢你的帮助。
    • @MatthewLoboWillis:太好了!我会在我的回答中更清楚地说明这一点。请记得点赞!
    • 认为自己被投了赞成票! :)
    【解决方案2】:

    不是通过 URL 传递促销代码,而是通过sessions

    【讨论】:

    • 感谢您的提示。我将研究 php 会话并尝试找出如何以这种方式实现解决方案。目前我的 PHP 技能还不够强大,无法包含它们。
    【解决方案3】:

    您可以解决它,同时保护自己免受跨站请求伪造 (CSRF) 的侵害。

    方法如下:

    • 生成哈希、guid 或类似的东西(使用 random_bytes 是一个不错的选择)。
    • 将此哈希保存在会话中。
    • 然后在表单的隐藏字段中添加哈希。
    • 在表单中使用 POST 方法而不是 GET。
    • 在接收请求的页面中,将给定的哈希值与会话中的哈希值进行比较,如果不匹配或不存在则抛出错误。

    在许多方面,这可以为您提供更好的保护。

    一些您可以使用的示例代码。

    <?php
    // In the page you have the form:
    
    // Generate the string
    $csrf_value = str_replace(['/', '+', '='], '', base64_encode(random_bytes(20)));
    // Save it in the session
    $_SESSION['csrf'] = $csrf_value;
    ?>
    
    <form action"a_page.php" method="POST">
        <input type="hidden" name="csrf" value="<?php echo $csrf_value ?>" />
        <input type="textfield" name="code" />
    </form>
    

    在接收请求的页面中:

    <?php
    if (isset($_POST['csrf']) 
            && strlen($_POST['csrf']) > 0 
            && strcmp($_SESSION['csrf'], $_POST['csrf']) === 0) {
        // All good, do your thing
    } else {
        // Show error, this guy is trying to trick you
    }
    

    【讨论】:

    • 感谢您的回复!我会试试的。我不知道 random_bytes,所以很高兴知道!
    猜你喜欢
    • 2023-02-13
    • 2020-10-17
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 2017-12-18
    • 2019-12-10
    • 2014-06-28
    • 2021-12-16
    相关资源
    最近更新 更多