如何从链接安全地获取变量?

时间:2016-04-06 10:47:27

标签: php security session

假设网站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查询添加和减去余额,然后重定向到广告的网址。

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

页面提供

这是什么解决方案?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:-1)

如果我理解了您的问题,您的目标是确保到达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)
 }