代码之家  ›  专栏  ›  技术社区  ›  Jonas Lundman

Apache htaccess:如果请求URI与cookie值不匹配,则拒绝

  •  3
  • Jonas Lundman  · 技术社区  · 6 年前

    我在Wordpress环境下工作,Apache服务器。我在上传中有一个名为 /restricted/ . 这里的所有内容(任何文件扩展名) 只能在以下情况下访问

    • 已设置名为“custom\u cookie”的cookie
    • 此cookie值必须与URL请求部分匹配

    /限制/ 我有一个文件夹 .htaccess 文件。所有操作都必须(首选)在htaccess文件中完成, htaccess文件。

    cookie是由functions.php设置的,没有问题 部分。关于安全的评论不是这里的问题

    这是一个url示例(localhost): http://localhost/komfortkonsult/wp-content/uploads/restricted/some-file.jpg?r=870603c9d23f2b7ea7882e89923582d7

    这个 第一 条件 ,一切 正在工作

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /komfortkonsult/
    
    RewriteCond %{REQUEST_URI} ^.*uploads/restricted/.*
    RewriteCond %{HTTP_COOKIE} !custom_cookie
    RewriteRule . /komfortkonsult/restricted.png [R,L]
    
    </IfModule>
    

    然而 下一部分 伊姆河 完全出乎意料 ,但我试过了 失败了 采用以下方法:

    RewriteCond %{HTTP_COOKIE} custom_cookie=(.*)$
    RewriteCond %1::%{REQUEST_URI} ^(.*?)::/\1/?
    RewriteRule . /komfortkonsult/restricted.png [R,L]
    

    同样地:

    RewriteCond %{QUERY_STRING} ^r=(.*)$
    RewriteRule ^/ - [E=COOKIE_MATCH:%1]
    RewriteCond %{HTTP_COOKIE} !custom_cookie="%{ENV:COOKIE_MATCH}"
    RewriteRule . /komfortkonsult/restricted.png [R,L]
    

    同样地:

    RewriteCond %{HTTP_COOKIE} custom_cookie=([^;]+) [NC]
    RewriteCond %{REQUEST_URI} !%1 [NC]
    RewriteRule . /komfortkonsult/restricted.png [R,L]
    

    等等。我真的很想把这个藏起来 .htaccess访问 .php 文件调用。但是 如果这是唯一的解决办法 为了我的建筑, (不是foo=bar,你的重定向在这里…)

    非常感谢你帮我解决这个问题。


    更新 (接受回答并工作后)

    一层 是隐藏的 (替换为图像) (一) 这个 (二) 用户 但是 不具备“编辑帖子”功能 .

    仅适用于上载到唯一文件夹中的文件 /限制/ . 该文件夹位于Wordpress原件中 /uploads/ 根。此限制材料不允许直接链接或访问搜索引擎等。没有浏览器缓存是允许的,限制必须立即工作后注销。还有更多。。。但我想你明白了。

    命名空间 'custom_cookie' h**p://example.com/workspace/ . 删除 'workspace/' 如果在根中。

    function intervik_theme_set_custom_cookie(){
    
        if(is_user_logged_in()){
    
            global $current_user;
    
            if(current_user_can('edit_posts')){
    
                if(!isset($_COOKIE['custom_cookie'])){
                    $cookie_value = $current_user->ID . '|' . $current_user->user_login . '|' . $current_user->roles;
                    $salt = wp_salt('auth');
                    $cookie_hash = hash_hmac('md5', $cookie_value, $salt);
                    setcookie('custom_cookie', $cookie_hash, time()+36, '/');
                    $_COOKIE['custom_cookie'] = $cookie_hash;
                } else {
                    $cookie_value = $current_user->ID . '|' . $current_user->user_login . '|' . $current_user->roles;
                    $salt = wp_salt('auth');
                    $cookie_hash = hash_hmac('md5', $cookie_value, $salt);
                    if($cookie_hash != $_COOKIE['custom_cookie']){
                        setcookie('custom_cookie', '', 1, '/');
                        unset($_COOKIE['custom_cookie']);
                    }
                }
    
            } else {
    
                if(isset($_COOKIE['custom_cookie'])){
                    setcookie('custom_cookie', '', 1, '/');
                    unset($_COOKIE['custom_cookie']);
                }
            }
    
        } else {
    
            if(isset($_COOKIE['custom_cookie'])){
                setcookie('custom_cookie', '', 1, '/');
                unset($_COOKIE['custom_cookie']);
            }
        }
    }
    add_action('init', 'intervik_theme_set_custom_cookie');
    

    如你所见,每一块饼干 对于 每个有效用户

    附件url筛选器的链接:

    function intervik_restricted_wp_get_attachment_url($url, $post_id){
        if(strpos($url, '/restricted/') !== FALSE){
            if(isset($_COOKIE['custom_cookie'])){
                $url = add_query_arg('r', $_COOKIE['custom_cookie'], $url);
            }
        }
        return $url;
    }
    add_filter('wp_get_attachment_url', 'intervik_restricted_wp_get_attachment_url', 10, 2);
    

    我们不允许任何其他查询字符串。注意,必须为大小添加更多筛选器,如 wp_get_attachment_image_src 但是直接联系媒体,这就足够了。

    更换 if(current_user_can('edit_posts') 和另一个 if(is_user_logged_in() ... 用户。然后使用i跳过管理后端中的过滤器 f(!is_admin() && strpos($url, '/restricted/')!== FALSE) ...

    最后是 .htaccess访问 文件,在 uploads/restricted/

    # BEGIN Intervik
    Options +FollowSymLinks
    Options All -Indexes
    
    <IfModule !mod_rewrite.c>
    Deny from all
    </IfModule>
    
    <IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
    </IfModule>
    
    RewriteEngine On
    RewriteCond %{HTTP_COOKIE}::%{QUERY_STRING} !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$)
    RewriteRule . /workspace/restricted.png? [R,L]
    
    # END Intervik
    

    我还将漂亮的PNG图像“restrictedaccesstimeout”放在Wordpress安装根目录中。对于无效的管理员,这也是库管理区域中的缩略图。上载筛选器或后端是另一个区域。

    把一些组织的文件和一些照片从谷歌和 你妻子。

    请评论

    它实际工作,欢迎您评论的缺陷或安全风险。然而,在我们的安装中,在这一层之上还有另一层PHP验证,但是对于不太重要的东西,我们需要速度。

    1 回复  |  直到 6 年前
        1
  •  3
  •   MrWhite    6 年前

    您在不同的尝试中获得了一些正确的位,但是您需要按照正确的顺序将它们组合在一起。

    RewriteEngine On
    
    # custom_cookie value is 32 char hex and must match the value of the "r" URL parameter
    RewriteCond %{HTTP_COOKIE}::%{QUERY_STRING} !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$)
    RewriteRule ^ /komfortkonsult/restricted.png [QSD,R,L]
    

    QSD 从重定向的URL中删除查询字符串需要标志(Apache 2.4+)。或者,如果您仍在使用Apache2.2,则可以附加 ? 替代

    请注意 RewriteBase 此处不需要。这个 <IfModule> 也应移除。这个 <IfModule mod_rewrite.c> 包装器只有在没有mod\u rewrite可用的情况下才需要。事实并非如此。如果modu rewrite不可用,那么您的条件将自动失败,访问将不受限制。在这种情况下,最好失败并出现错误,并且禁止访问(对于每个人)。

    • cookie值是32个字符的十六进制值(如您的示例中所示)。
    • 这个 r URL参数始终是 第一 URL参数(如您的示例所示)。

    RewriteRule 指令如下:

    RewriteRule ^ - [F]
    

    如何工作。。。

    • 除了你的一个例子之外,其他所有例子都忽略了一点,那就是 r URL参数是 查询字符串 ,而不是URL路径。这个 REQUEST_URI QUERY_STRING 服务器变量。

    • %{HTTP_COOKIE}::%{QUERY_STRING} -那个 cookie HTTP请求头与 查询字符串 使用分隔符( :: .

    • !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$) -这就是 CondPattern公司 符合 \b 是单词边界,所以我们只匹配这个特定的cookie。这个cookie的值是 捕获 使用 ([0-9a-f]{32}) . 然后我们跳过cookie头中剩余的字符,直到找到分隔符( ). 在此之后,我们将与 (价值 中的服务器变量 测试字符串 \1

    • ! 上的前缀

    为什么你的尝试没有成功。。。

    RewriteCond %{HTTP_COOKIE} custom_cookie=(.*)$
    RewriteCond %1::%{REQUEST_URI} ^(.*?)::/\1/?
    
    • 这假设您的cookie是系统中的最后一个cookie Cookie 标题。这很难保证。
    • ),所以这永远不会匹配。它假定您的URL的格式为: http://localhost/870603c9d23f2b7ea7882e89923582d7
    RewriteCond %{QUERY_STRING} ^r=(.*)$
    RewriteRule ^/ - [E=COOKIE_MATCH:%1]
    RewriteCond %{HTTP_COOKIE} !custom_cookie="%{ENV:COOKIE_MATCH}"
    

    查询字符串

    • 第一个 重写规则 .htaccess COOKIE_MATCH
    • CondPattern公司 是正则表达式,不是普通字符串,所以 %{ENV:COOKIE_MATCH} 未计算-它被视为文本字符串。您还将其括在双引号中,双引号也不是cookie值的一部分。
    RewriteCond %{HTTP_COOKIE} custom_cookie=([^;]+) [NC]
    RewriteCond %{REQUEST_URI} !%1 [NC]
    
    • 同样,您要比较的是URL路径,而不是查询字符串。然而,如上所述 %1 CondPattern公司 ,所以这被视为一个文本字符串。

    %{VARIABLE} (和 %1 etc)表达式在 我们需要使用一个看似复杂的表达式,该表达式使用以下形式的regex backreference:

    %{VAR1}@@%{VAR2} ^(.+)@@\1$