Можно ли ограничить количество параметров $_GET приложением Zend Framework, использующим Zend_Cache_Backend_Static для кэширования статических страниц в виде HTML

Я только что настроил статическое кэширование страниц, используя Zend_Cache_Backend_Static для обслуживания кэшированных html-файлов в моем приложении, и это прекрасно работает. Единственное, что меня беспокоит, - это способ кэширования файлов с параметрами $_GET. Поскольку он автоматически создает структуру папок, которая сопоставляется с указанным маршрутом URL, является ли это потенциальной угрозой безопасности в случаях, когда большое количество параметров $_GET может быть намеренно добавлено к существующим страницам? Или максимальная глубина каталога или максимальная длина файла?

Например: на данный момент я кеширую свои страницы в /public/cache/static/ так что используя стандартный роутер /module/controller/action/param1/val1/param2/val2 или стандартная строка запроса /module/controller/action?param1=val1&param2=val2 создаст следующие структуры каталогов:

/public/cache/static/module/controller/action/param1/val1/param2/val2.html 
/public/cache/static/module/controller/action?param1=val1&param2=val2.html

Предоставление людям доступа к созданию структуры каталогов таким образом (хотя и ограниченным) меня немного беспокоит. И Zend_Cache_Backend_Static, и соответствующий Zend_Cache_Frontend_Capture должны быть установлены в ini-файле, а не через фабрику Zend_Cache, и, похоже, не имеют никаких параметров настройки.

Может быть, это просто случай замены маршрутизатора по умолчанию на пользовательские маршруты, ограничивающие количество переменных $_GET? Возможно ли это, или мне нужно указать именно те переменные, которые мне нужны для каждого маршрута (не конец света, а немного более ограничивающий)

Обновить:

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

RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{DOCUMENT_ROOT}/cached/index.html -f
RewriteRule ^/*$ cached/index.html [L]

RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{DOCUMENT_ROOT}/cached/%{REQUEST_URI}\.html -f
RewriteRule .* cached/%{REQUEST_URI}\.html [L]

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^.*$ index.php [NC,L]

Если запрос попадает на страницу в статическом кэше, он отправит эту HTML-страницу. Если нет, то он ударит по Zend Framework и сгенерирует его.

Я мог бы добавить следующее в начало:

RewriteCond %{QUERY_STRING} \S
RewriteRule [^\?]+ /$0? [R=301,L]

Который сотрет мою строку запроса вообще. Это нормально, поскольку я все еще могу передавать переменные $_GET при использовании метода URL-пути Zend Framework (который я также ограничил, предоставляя очень явные маршруты). Но возможно ли это сделать без перенаправления?

2 ответа

Решение

Итак, RewriteRule, удаляющий строку запроса, будет работать без перенаправления.

Проблема (я подозреваю) в том, что Zend_Cache_Backend_Static использует $_SERVER['REQUEST_URI'] где-то вдоль линии и, следовательно, получает доступ к исходному имени файла. Мои знания о mod_rewrite довольно малы, и я не осознавал, что это значение не изменилось.

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

Во-первых, для стандартных строк запроса:

Удалите строку запроса в начале моего mod_rewrite без перенаправления:

RewriteCond %{QUERY_STRING} \S
RewriteRule [^\?]+ /$0?

Затем в моем index.php я изменяю $_SERVER['REQUEST_URI'], чтобы он соответствовал перенаправлению, удаляя строку запроса, что означает, что мне больше не нужно взламывать ZF:

$queryIndex = strpos($_SERVER['REQUEST_URI'], '?');
if($queryIndex !== false) {
    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 0, $queryIndex);
}

Теперь это предотвратит интерпретацию ЛЮБОЙ строки запроса моим приложением. Поэтому для передачи переменных на страницы я использую параметры пути URL-адреса Zend Framework. Чтобы они не создавали чрезмерно глубоких папок кэша, я заменил маршрут по умолчанию на несколько явно определенных маршрутов в Bootstrap:

$frontController = Zend_Controller_Front::getInstance(); 
$router = $frontController->getRouter();

$route = new Zend_Controller_Router_Route(
    ':module/:controller/:action',
    array(
        'module' => 'default',
        'controller' => 'index',
        'action' => 'index'
    )
);

$router->addRoute('default', $route);

$route = new Zend_Controller_Router_Route(
    'article/:alias',
    array(
        'module' => 'default',
        'controller' => 'article',
        'action' => 'index',
        'alias' => ''
    )
);

$router->addRoute('article', $route);

Здесь я заменил маршрут по умолчанию, поэтому дополнительные параметры не допускаются. Поэтому любые действия, которые требуют параметров, должны быть явно установлены, например, на моем втором маршруте. Это означает, что потенциально может быть много определенных маршрутов. К счастью, это не так в моем конкретном приложении.

Способ обойти такое ограничение ограничений и разрешить использование некоторых параметров GET через URL-пути ZF - это установить ограничение на количество слешей в REQUEST_URI, эффективно ограничивая максимальную глубину каталогов статического кеша страниц (10 ниже). Это также может быть изменено в index.php:

if(substr_count($_SERVER['REQUEST_URI'], '/') > 10) {
    preg_match_all("/\//", $_SERVER['REQUEST_URI'] ,$capture, PREG_OFFSET_CAPTURE);
    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 0, $capture[0][9][1]);
}

Идеальным способом было бы определить это как RewriteCond, но я не уверен, что можно подсчитать количество параметров GET, используя mod_rewrite.

Поэтому, вероятно, лучшим решением будет перенаправление на отдельный скрипт php, который решает, использовать ли кэшированные html-файлы.

<?php

if (count($_GET) >= 20) {
  require __DIR__ . 'index.php';
} else {
  require '/path/to/cache.html';
}
Другие вопросы по тегам