Yii的。重定向前检查URL以防止攻击

时间:2014-03-20 17:13:08

标签: url redirect yii sanitize

我的 $ returnUrl var来自表单,其中包含控制器/操作:

<?=CHtml::hiddenField('returnUrl', 
    Yii::app()->urlManager->parseUrl(Yii::app()->request)
);?>

在控制器中我有这样的事情:

$returnUrl = Yii::app()->request->getPost('returnUrl');
$returnUrl = array($returnUrl);
$this->redirect($returnUrl);

但它也有效,然后我将 $ returnUrl 控制器/操作更改为外部网站网址。例如:如果我将 http://google.com 添加到 $ _ POST [&#39; returnUrl&#39;] 而不是网站/索引 yii将我重定向到 / http://google.com ,没有任何错误。

在重定向之前检查 $ returnUrl 的最佳方法是什么?我如何将 $ returnUrl 与我的路线或控制器/操作进行比较?

现在我做下一个:

$returnUrl = Utils::sanitizeReturnUrl($returnUrl);    
...
class Utils 
{
    public static function sanitizeReturnUrl($returnUrl)
    {
        if (!preg_match('~^([-a-z0-9_]+|[-a-z0-9_]+/[-a-z0-9_]+)+$~i', $returnUrl))
        {
            $returnUrl = Yii::app()->homeUrl;
        }

        return $returnUrl;
    }
 }

但可能存在更合适的方式

1 个答案:

答案 0 :(得分:0)

正确的方法是解析returnUrl并删除方案(http://https://)和其他不安全的东西。

<?php
$returnUrl = 'http://username:password@hostname/path?arg=value#anchor';
$returnUrl = sanitizeReturnUrl($returnUrl);
echo $returnUrl; 
/**
 * now you got:
 * hostname/path?arg=value#anchor
 */

function sanitizeReturnUrl ($url)
{
    $urlArray = parse_url($url);
    $url = $urlArray['host'] . $urlArray['path'] . '?' . $urlArray['query'] . '#' .     $urlArray['fragment'];
    return $url;
}