在开始之前,我对PHP完全不熟悉。这可能是一个愚蠢的错误,我可能以最糟糕的方式做到这一点。
我有这段代码:
<?php
if (!isset($_GET['p'])) {
$url .= '?p=home';
header('Location:' . $url);
exit;
}
elseif (!isset($_GET['sp'])) {
header("Location: ".$_SERVER['REQUEST_URI'].'&sp=index.php';);
die();
}
include('/Page/' . htmlspecialchars($_GET["p"]) . '/' . htmlspecialchars($_GET["sp"]));
?>
基本上,网址格式为www.example.com/?p=PAGE&sp=SUBPAGE.php
此内部格式为/Page/PAGE/SUBPAGE.php
原因:
每个帖子&#39;将拥有它自己的文件夹以获取它的资源。 (?p=
)然后,他们可以在文件夹中放置任何内容,并使用SUBPAGE (&sp=)
链接到该文件夹。
这可以保持所有内容的整理,并阻止任何内部链接到/page/
区域以外的任何地方。
出了什么问题:
如果没有Page(p)集,我需要添加?p=home
作为默认值,如果它们没有SubPage(sp)集,我需要默认添加&sp=index.php
。
如果没有Page,则SubPage将重置为默认值。
如果您在www.example.com/?p=blog
页面上,则会在不删除页面的情况下添加子页面(?p=blog
至?p=blog&sp=index.php
)
但是,如果没有页面,则子页面将重置为默认值。
问题:
我怎么能这样做?
提前谢谢你。
答案 0 :(得分:1)
我会以不同的方式处理这种情况。
为页面和内页设置一些变量,使用默认值,只有在$_GET
参数设置
$page = 'home';
$inner_page = 'index.php';
if( isset( $_GET['p'] ) )
{
$page = htmlspecialchars( $_GET['p'] );
}
if( isset( $_GET['sp'] ) )
{
$inner_page = htmlspecialchars( $_GET['sp'] );
}
include $_SERVER['DOCUMENT_ROOT'] . '/Page/' . $page . '/' . $inner_page;
我也添加了$_SERVER['DOCUMENT_ROOT']
,因为如果您使用/Page
,那么它是绝对路径,可能不是您所期望的那样,因此预先$_SERVER['DOCUMENT_ROOT']
确保您正在查看您的网络目录中的路径。
还有其他值得注意的事情;不要假设数据是好的,人们可以尝试操纵包含的文件。
http://your.domain/index.php?p=../../../../../&sp=passwd
因此,首先要尝试清理数据是值得的。
答案 1 :(得分:0)
您当前的代码存在严重的安全漏洞。
编写应用时最重要的规则之一,永远不要信任来自客户端的数据。总是假设,他们会向您发送错误或虚假的数据。
我建议您创建一个配置文件,定义允许的路由。
通过执行以下行,您只允许任何人访问您的网络服务器可读的任何文件。
include('/Page/' . htmlspecialchars($_GET["p"]) . '/' . htmlspecialchars($_GET["sp"]));
如果您为$ _GET ['p']发送了一个有效值,那么会发生什么?$ _GET ['sp']:
"/../../../../../../../../../../../etc/apache2/httpd.conf"
在此示例中,它将输出您的apache配置文件(假设这是正确的路径,如果不是黑客可以继续尝试路径,直到找到它。)
为避免这种情况,您有两种解决方案。
1#快速修复 - 您可以消毒&amp;过滤$ _GET ['p']和$ _GET ['sp']以确保您没有得到'/../'
。请务必至少添加file_exists
,以避免收到不需要的警告消息。
2#更优雅的修复 - 您可以创建一个包含您正在接受的路由的配置文件。如果您使用的是框架,那么您很可能拥有可以使用的路由类或路由模块。否则,如果您想要实现自己的基本路由机制,您可以做一些像您的情况一样简单的事情:
<?php
/**
* Defines the different routes for the web app
* @file : config.routes.php
*/
return array(
'page1' => array(
'index.php',
'subpage2.php',
'subpage3.php',
),
);
然后,你要检查你的代码是否允许$ _GET ['p']和$ _GET ['sp']值。
<?php
// Load config file containing allowed routes
$allowedRoutes = require(__DIR__ . '/config.routes.php');
$defaultPage = 'home';
$defaultSubPage = 'index.php';
$page = isset($_GET['p']) ? $_GET['p'] : defaultPage;
$subPage = isset($_GET['sp']) ? $_GET['sp'] : $defaultSubPage;
// If it is an invalid route, then reset values to default
if (!isset($allowedRoutes[$page][$subPage]))
{
$page = $defaultPage;
$subPage = $defaultSubPage;
}
include $_SERVER['DOCUMENT_ROOT'] . '/Page/' . $page . '/' . $subPage;