漏洞是可以发送任何类型的相对路径在$lang
. 如果用户可以上传文件并找出他们在服务器上的真实路径,这尤其危险。
例子:
- 黑客可能会使用您网站的某些文件上传功能进行上传
evil.php
。黑客可能知道/已经发现/猜测它存储在/var/www/uploads/evil.php
,并且您的应用程序在/var/www/html
.
/var/www/uploads
现在,如果无法通过 HTTP 访问,通常没有人可以运行此文件。
- 但是,可以打开
http://example.com/index.php?lang=../../uploads/evil
并猜猜是什么,它将包括languages/../../uploads/evil.php
哪个将解析为/var/www/uploads/evil.php
!
如果有任何其他文件可用于通过访问它们并调用它们来利用某些东西,例如通常受密码保护的目录中的文件(例如phpMyAdmin),这当然也可以在没有文件上传的情况下工作。
如果你现在认为“这是相当多的假设和'可能'和'如果在那里,你需要非常幸运才能成功”然后小心 - 尽管在你做一个 URL 的地方有一些明显的公开漏洞打个电话,比方说,你可以超越服务器或删除数据库,最危险的是需要多个拼图才能使漏洞利用工作的那些,因为它们很长一段时间都未被发现,而且很难理解如何一旦发生这种情况,服务器实际上就被黑客入侵了,您家门口自然会有一个更有经验,因此也更危险(可能是隐形)的黑客。如果有人下定决心要找到安全漏洞(因为他们的实际目标是攻击您的网站或您,
有多种解决方案。
正如 u_mulder 所建议的,如果你只有ar
然后en
检查它是否是其中一个。
如果您有更多语言,您可以创建一个包含允许值列表的数组,并检查发送的语言是否在该数组中,例如:
$languages = ['de', 'en', 'ar', 'jp', 'fr'];
if(in_array($_GET['lang'], $languages)) {
$selectedLanguage = $_GET['lang'];
} else {
$selectedLanguage = 'en'; // default
// Note that you could also show an error "invalid language" instead
}
如果您想通过仅允许文件夹中存在的文件来控制这一点,您还可以验证该语言是否仅包含字母(或您需要的任何内容,只要您确保它可能不包含点或斜杠等) :
if(preg_match("/^[a-z]*$/", $_GET['lang'])) { ... }
请注意,使用这种方法,您还应该明确地检查指定的文件是否存在,否则仍然可以通过指定无效语言来拥有无语言站点(特别是因为include
不会在不存在的文件上引发错误,不像require
)。