正则表达式 unix ./ /././.



我在后台运行php管理面板和纯ftpd服务器。

我想检查用户为特定用户提供的路径是否不包含..//..或/。。/

我正在使用

一个php框架Nette,对于此验证,我正在使用addRule(Form::P ATTERN,'error message',$pattern((Nette api-docs:https://api.nette.org/2.4/Nette.Forms.Form.html,Nette docs:https://doc.nette.org/en/2.4/form-validation

谢谢你的时间

我不知道

你是否对其他解决方案持开放态度,但如果是我,我不会尝试在路径上使用正则表达式,因为 PHP 有更简单的方法。

如果是我,我会这样做:

<?php
// You know your users are limited to their own home directory
$user_base_dir = '/home/skunkbad/';
// And they supply some path that attempts directory transversal
$supplied_path = '/home/skunkbad/../../etc/';
// Realpath in this case would return "/etc/"
$realpath = realpath( $supplied_path );
// So the check to see if the user base directory is in the path that realpath returns would fail
if( stripos( $realpath, $user_base_dir ) !== 0 )
    echo 'Invalid Path!';

请参阅:http://php.net/manual/en/function.realpath.php

以及:http://php.net/manual/en/function.stripos.php

谢谢你@BrianGottier,

但是realpath($path)检查文件是否真的存在于文件系统中,脚本需要权限才能执行......所以,自从我知道我在寻找什么以来,我用谷歌搜索了一下,并从 php.net 和社区的一些东西中提出了这个:

/**
 * @param $path
 * @param $baseDir
 * @return bool
 */
protected function isDirValid($path, $baseDir)
{
    if (stripos($path, '\'))
        return false;
    $path = str_replace('/', '/', $path);
    $path = str_replace('\', '/', $path);
    $parts = array_filter(explode('/', $path), 'strlen');
    $absolutes = [];
    foreach ($parts as $part)
    {
        if ('.' == $part)
            continue;
        if ('..' == $part)
        {
            array_pop($absolutes);
        } else {
            $absolutes[] = $part;
        }
    }
    $realDir = '/' . implode('/', $absolutes);
    if (stripos($realDir, $baseDir) !== 0)
        return false;
    return true;
}

最新更新