Apache htaccess: Запретить, если REQUEST_URI не соответствует значению cookie - PullRequest
0 голосов
/ 09 октября 2018

Итак, после поиска решения по всему сообществу мой вопрос выглядит следующим образом:

Я работаю в среде Wordpress, сервере Apache.У меня есть папка в загрузках с именем /restricted/.Все здесь (любое расширение файла) может быть доступно только в том случае, если :

  • Файл cookie с именем 'custom_cookie' установлен
  • И это значение cookie должно быть частичным совпадением запроса URL

. Если эти условия не выполняются, изображение передается.Внутри этой папки /restricted/ я получил файл .htaccess.Все должно (предпочтительно) быть сделано в этом файле htaccess, не в корневом файле htaccess.

Файл cookie устанавливается functions.php, никаких проблем с этой частью нет.И комментарии о безопасности здесь не вопрос

Это пример URL (localhost): http://localhost/komfortkonsult/wp-content/uploads/restricted/some-file.jpg?r=870603c9d23f2b7ea7882e89923582d7

Условие first Cookieс именем custom_cookie установлено , все работает с этим:

<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>

Тем не менее, следующая часть Im полностью отсутствуетсиний , но я попытался и потерпел неудачу со следующими подходами:

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, ваши перенаправления идут сюда ...)

Любые другие подходы к моим целям приветствуются.

Большое спасибо за помощь в этом.

/ Intervik


Обновление (после принятого ответа и работы) пример использования

Цели: один уровень защиты в одиночной установке Wordpress.Все файлы мультимедиа, изображения или другие файлы, загруженные и прикрепленные к страницам, скрыты (заменены изображением) , если A) , пользователь не являетсявошел в систему или B) Пользователь зарегистрирован в , но не с возможностью 'edit_post' .

Но ограничение распространяется только на файлы, загруженные в уникальную папку с именем /restricted/.Папка находится в корневом каталоге Wordpress /uploads/.Этот запрещенный материал не может быть напрямую связан или доступен для поисковых систем и т. П.И еще ... но я думаю, что вы поняли.

Пространство имен 'custom_cookie' является просто примером.А примеры, показывающие установку Wordpress, находятся в подпапке на localhost.НРАВИТСЯ h**p://example.com/workspace/.Удалите 'workspace/', если он находится в корне.

Архитектура cookie, functions.php

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');

Как видите, каждый файл cookie уникален для каждого действительного пользователя , для каждого периода +36 секунд (достаточно для загрузки страницы - но используйте +120 в течение 2 минут).Этот «токен» применяется к каждому запросу, отправляемому на сервер:

Ссылка на фильтр 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-изображение «Тайм-аут ограниченного доступа» в корень установки Wordpress.Это также используется в качестве эскиза в области администрирования библиотеки для недействительных администраторов.Фильтр загрузки или серверная часть - это еще одна область.

Мы не защищаем здесь финансовые планы Englands, но мы хотим сохранить некоторые документы для организации и некоторые изображения от Google и отваша жена.

Пожалуйста, прокомментируйте

Это действительно работает, и вы можете прокомментировать недостатки или угрозы безопасности.Тем не менее, в нашей установке есть еще один уровень проверки с PHP выше этого уровня, но нам нужна скорость для не столь важных вещей.

1 Ответ

0 голосов
/ 25 октября 2018

У вас есть несколько правильных битов в разных попытках, но вам нужно собрать их в правильном порядке.

Вместо этого попробуйте следующее:

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 (Apache 2.4+) необходим для удаления строки запроса из перенаправленного URL.В качестве альтернативы, если вы все еще используете Apache 2.2, вы можете вместо этого добавить ? к susbstitution .

Обратите внимание, что RewriteBase здесь не требуется.<IfModule> также следует удалить.Оболочка <IfModule mod_rewrite.c> требуется только в том случае, если она предназначена для работы без наличия mod_rewrite.Это не.Если mod_rewrite недоступен, то ваши условия просто не будут выполняться молча, и доступ будет неограниченным.В этом случае предпочтительным является сбой с ошибкой, а доступ запрещен (для всех).

Допущения:

  • Значение файла cookie - 32шестнадцатеричное значение символа (как в вашем примере).
  • Параметр URL r всегда является параметром URL first (как в вашем примере).

Вы упомянули «любое расширение файла», однако, перенаправление на изображение действительно «работает», только если изображение запрашивается в первую очередь.Если у вас есть файлы, отличные от изображений, может быть предпочтительнее просто вернуть 403 Forbidden.(Строго говоря, отправка 403 - это правильный ответ, а не 302, за которым следует 200 OK.) Чтобы отправить 403 вместо этого, просто измените директиву RewriteRule следующим образом:

RewriteRule ^ - [F]

Как это работает ...

  • Важным моментом, который пропущен во всех примерах, кроме одного, является то, что параметр r URL является частью Строка запроса , а не URL-путь.Серверная переменная REQUEST_URI содержит только URL-путь, что, в частности, исключает строку запроса.Чтобы сопоставить строку запроса, необходимо сравнить ее с серверной переменной QUERY_STRING.

  • %{HTTP_COOKIE}::%{QUERY_STRING} - Заголовок HTTP-запроса cookie объединяется со строкой запроса с использованием разделителя (::), который гарантированно не появится ни в одном из значений.Это формирует TestString .

  • !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$) - Это CondPattern , который соответствует TestString .\b - это граница слова, поэтому мы сопоставляем только этот конкретный файл cookie.Значение этого файла cookie захвачено с использованием ([0-9a-f]{32}).Затем мы пропускаем все оставшиеся символы в заголовке cookie, пока не доберемся до нашего разделителя (::).После этого мы сопоставляем строку запроса (значение серверной переменной QUERY_STRING в TestString ).«Волшебство» - это обратная ссылка \1 к первой захваченной группе, т.е.значение cookie.

  • Префикс ! в CondPattern отменяет весь шаблон.Таким образом, условие успешно, когда этот шаблон не совпадает, т.е.когда значения параметров cookie и URL отличаются (или не присутствуют вообще).

Почему ваши попытки не сработали ...

RewriteCond %{HTTP_COOKIE} custom_cookie=(.*)$
RewriteCond %1::%{REQUEST_URI} ^(.*?)::/\1/?
  • Предполагается, что ваш файл cookie является последним файлом cookie в заголовке Cookie.Это трудно гарантировать.
  • Вы пытаетесь сопоставить значение cookie со всем URL-путем (REQUEST_URI), поэтому это никогда не будет совпадать.Предполагается, что ваш URL имеет вид: http://localhost/870603c9d23f2b7ea7882e89923582d7.
RewriteCond %{QUERY_STRING} ^r=(.*)$
RewriteRule ^/ - [E=COOKIE_MATCH:%1]
RewriteCond %{HTTP_COOKIE} !custom_cookie="%{ENV:COOKIE_MATCH}"

Хорошо, вы проверяете строку запроса для значения параметра URL,Однако ...

  • Первый RewriteRule никогда не совпадает, потому что URL-путь никогда не начинается с косой черты в контексте для каталога (.htaccess).Следовательно, переменная окружения COOKIE_MATCH никогда не устанавливается.
  • CondPattern является регулярным выражением, а не простой строкой, поэтому %{ENV:COOKIE_MATCH} не оценивается - она ​​рассматривается как литеральная строка,Вы также заключили это в двойные кавычки, которые также не являются частью значения cookie.
RewriteCond %{HTTP_COOKIE} custom_cookie=([^;]+) [NC]
RewriteCond %{REQUEST_URI} !%1 [NC]
  • Опять же, вы сравниваете с URL-путем, а не строкой запроса.Однако, как уже упоминалось выше, обратная ссылка %1 не оценивается в CondPattern , так что в любом случае это рассматривается как буквальная строка.

Именно поэтому %{VARIABLE}%1 и т. д.) выражения не оцениваются в CondPattern , в котором нам нужно использовать, казалось бы, сложное выражение, использующее обратную ссылку на регулярное выражение в форме:

%{VAR1}@@%{VAR2} ^(.+)@@\1$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...