【问题标题】:How to securely get variables from a link?如何安全地从链接中获取变量?
【发布时间】:2016-04-06 10:47:26
【问题描述】:

假设一个网站 xyz.com 正在使用 JavaScript 代码展示来自我的广告网络 example.com 的广告:

<script type='text/javascript' src='http://example.com/click.php?id=12345678'></script>

将广告显示为:

click.php
<a href="http://example.com/process.php?var1=var1&var2=var2">
<img src="http://example.com/ads/banner.png"/></a>

当点击链接时,它会被带到process.php,在那里我使用一些 MySQL 查询来增加和减少余额,然后重定向到广告的 URL。

process.php
$ua = $_SERVER['HTTP_USER_AGENT'];
$ip = $_SERVER['REMOTE_ADDR'];
//invalid click
if($_SERVER['HTTP_REFERER']==null || $_SERVER['HTTP_USER_AGENT']==null) {
header("location: http://example.com");
exit;
}

我想添加到click.php 的唯一会话并在process.php 检索它以防止无效点击。我该怎么做?

更新: 下面的答案解决了一半的问题,但用户仍然可以使用 iframe 和 img 标签发送虚假点击,如下所示:

<img src="http://example.com/click.php?id=12345678" height="1px" width="1px"/>

这些点击仍在计算中,因为请求由页面click.phpprocess.php 提供服务

解决办法是什么?

【问题讨论】:

标签: php security session


【解决方案1】:

我已经找到了解决问题的方法,并且效果很好: 编辑: 我找到了一个解决方案: 使用click.php 的会话设置变量并使用随机数将其发送到process.php

click.php
$_SESSION["ip"]=$ip;
$_SESSION["ua"]=$ua;
$rand="".rand(1,9)."".rand(0,9)."".rand(0,9)."".rand(0,9)."".rand(0,9)."".rand(0,9)."";
$_SESSION["hash"]=$rand;
<a href="http://example.com/process.php?hash=$rand">
<img src="http://example.com/ads/banner.png"/></a>

并从process.php的会话中获取值

process.php
$hash=$_GET["hash"];
$ua=$_SESSION["ua"];
$ip=$_SESSION["ip"];
$rand=$_SESSION["hash"];

// Invalid Redirection Protection
if(($hash!=$rand) || ($ip!=$_SERVER['REMOTE_ADDR']) || ($ua!=$_SERVER['HTTP_USER_AGENT'])) {
header("location: http://example.com");
session_destroy();
exit;
}

【讨论】:

    【解决方案2】:

    如果我理解您的问题,您的目标是确保到达http://example.com/process.php 的任何请求都来自http://example.com/click.php 创建的链接

    (请注意,这仅意味着任何试图颠覆您的系统的人都需要获取http://example.com/click.php 并在获取http://example.com/process.php 之前提取相关数据。它提高了一点标准,但距离万无一失还有很长的路要走)。

    PHP 已经有一个非常好的会话机制。通过嵌入在脚本输出中的 url 来适应传播很容易(因为你不能依赖 cookie 可用)。然而,由于它依赖于写入存储,它的可扩展性不是很好。

    我会使用具有有限数量的可预测良好状态(以及更多数量的不良状态)的令牌。这意味着使用某种加密。虽然对称密码可以提供最容易理解的模型,但它比基于散列的模型更难实现。

    使用哈希模型,您可以使用秘密盐对您已经发送的值进行哈希处理,并将哈希包含在请求中。然后在接收端,重复练习并将生成的哈希与发送的哈希进行比较。

    为防止重复提交,您需要在请求变量中使用一些其他标识符 - 一个大的随机数、客户端 IP 地址、时间......

    define('SALT','4387trog83754kla');
    
    function mk_protected_url($url)
    {
        $parts=parse_url($url);
        $args=parse_str($parts['query']);
        $args['timenow']=time();
        $args['rand']=rand(1000,30000);
        sort($args);
        $q=http_build_query($args);
        $args['hash']=sha1(SALT . $q);
        $q=http_build_query($args);
        return $parts['scheme'] . '://'
            .$parts['host'] . '/'
            .$parts['path'] . '?' . $q;
    }
    
    function chk_protected_url($url)
    {
        $parts=parse_url($url);
        $args=parse_str($parts['query']);
        $hash=$args['hash'];
        unset($args['hash'];
        // you might also want to validate other values in the query such as the age
        $q=http_build_query($args);
        $check=sha1(SALT . $q);
        return ($hash === $check)
     }
    

    【讨论】:

    • 我不知道您对“安全”的定义是什么,也不知道您需要提供多少容量。在欧洲使用这样的 cookie 而不提供通知是非法的。
    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多