是否可以将$_GET参数的数量限制为使用Zend_Cache_Backend_Static将静态页面缓存为HTML的Ze



我刚刚使用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框架并生成它。

我可以在开头添加以下内容:

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

这将完全擦除我的查询字符串。这很好,因为我仍然可以使用Zend Framework的URL路径方法传递$_GET变量(我也通过提供非常明确的路由来限制它)。但是,在不重定向的情况下可以做到这一点吗?

理想的方法是将其定义为RewriteCond,但我不确定是否可以使用mod_rewrite计算GET参数的数量。

因此,最好的解决方案可能是重定向到一个独立的php脚本,该脚本决定是否使用缓存的html文件。

<?php
if (count($_GET) >= 20) {
  require __DIR__ . 'index.php';
} else {
  require '/path/to/cache.html';
}

OK,因此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);
}

这将阻止我的应用程序解释ANY查询字符串。因此,为了将变量传递到页面,我使用Zend Framework url路径参数。为了防止这些创建过深的缓存文件夹,我在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);

在这里,我已经替换了默认路由,因此不允许使用其他参数。因此,任何需要参数的操作都必须明确设置,例如在我的第二个路由中。这意味着可能存在许多已定义的路线。值得庆幸的是,在我的特定应用程序中并非如此。

通过ZF URL路径限制路由并允许一些GET参数的一种方法是对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]);
}

相关内容

  • 没有找到相关文章

最新更新