PHP 安全地包含文件 + 处理无效参数
Posted
技术标签:
【中文标题】PHP 安全地包含文件 + 处理无效参数【英文标题】:PHP Securely include files + handle invalid parameters 【发布时间】:2018-04-28 17:59:55 【问题描述】:我遇到了一个小问题。如果参数无效,我想安全地包含基于来自子目录 + 句柄的 $_GET 参数的文件。
<?php
if(isset($_GET['p']) && $_GET['p'] == 'fahrzeuge')
include 'includes/cars.php';
if(isset($_GET['p']) && $_GET['p'] == 'impressum')
include 'includes/impressum.php';
if(isset($_GET['p']) && $_GET['p'] == 'home')
include 'includes/home.php';
if(isset($_GET['p']) && $_GET['p'] == 'anfahrt')
include 'includes/anfahrt.php';
if(isset($_GET['p']) && $_GET['p'] == 'about')
include 'includes/about.php';
?>
这是我的代码。对不起,我知道这是解决这个问题的一种菜鸟方式。我该如何改进它?任何建议/帮助将不胜感激
【问题讨论】:
【参考方案1】:这是最快和最好的方法,我是短代码的粉丝 并从 (HACKBUGZ PHP) 中找到了这个。
您有一个包含数组键和数组值的数组。
示例 1
<?php
$PAGES = array();
$PAGES = [
'home' => 'home.html'
,'about' => 'about.php'
,'contact' => 'somedir/contact.php'
];
@include(substr($PAGES[$_GET['p']] ?? ('home'), 0, 255));
exit;
?>
您可以有不同的查询名称、文件名、文件类型和目录。
如果文件不存在,@ 会捕获包含错误。
substr($PAGES, 0, 255) 将 uri 削减为 255 个字符(如果你不喜欢这样的话 不做就行了)
($PAGES[$_GET['p']] ?? ('home')) 检查查询 (array_key) 是否存在于数组中,如果不存在 'home' 将是默认值 p>
示例 2(无 substr)
<?php
$PAGES = array();
$PAGES = [
'home' => 'home.html'
,'about' => 'about.php'
,'contact' => 'somedir/contact.php'
];
@include($PAGES[$_GET['p']] ?? ('home'));
exit;
?>
【讨论】:
【参考方案2】:我会使用ternary 来设置一个变量来告诉页面要包含的内容。
这与Ofir Baruch 的回答非常相似,只是要短得多。
$pages = array('about','contact','home');
$p = isset($_GET['p']) && in_array($_GET['p'], $pages)? $_GET['p'] : 'home';
include "includes/$p.php";
基本上,您有一系列可能的页面。在三元中,我们检查是否设置了$_GET['p']
(isset()
),并检查它包含的值是否在数组中。如果是,我们将$_GET['p']
用作$p
,如果不是,我们将$p
设置为home
,这意味着如果$_GET['p']
未设置或不设置,home
将始终为默认值根据数组的有效页面。
【讨论】:
【参考方案3】:设置合法页面数组。检查一次是否设置了$_GET['p']
,如果设置了,则将其值(在转义后)分配给变量$p
。
然后检查请求的页面 ($p
) 是否在您的 pages 数组中定义,如果是 - 包括它。
$pages = array('about','contact','home');
$p = 'home'; //Default page
if(isset($_GET['p']))
$p = $_GET['p']; //no need to escape as we compare it to predefined values as @Yoshi suggested
if(in_array($p, $pages))
include 'includes/'.$p.'.php';
else
include 'includes/home.php';
【讨论】:
感谢您的快速回复。如果可行,我将对其进行测试并接受您的问题。或者如果它不能按我想要的方式工作。我会让你知道或问你 当然,没问题。更新我。 真的有必要做htmlspecialchars()
并检查一个数组吗?如果$p
包含特殊字符,它就不会加载任何内容,因为该值不会在数组中。如果是页面名称,则必须是文件名,这意味着无论如何都不应该有任何特殊字符,除非我猜可能是一个空格
嘿,它确实有效 + 但如果用户试图修改参数,我也想处理。在这种情况下,页面不包含任何内容并且看起来很糟糕,因此我想包含主页。恐怕这很简单:P
不要转义p
,只用它作为数组键,值来包含页面。以上是关于PHP 安全地包含文件 + 处理无效参数的主要内容,如果未能解决你的问题,请参考以下文章