我尝试从文件中读取一个常量,并能够根据需要更改这个常量。
因此,当需要写入该常量时(在本例中通过GET),就在我想重新加载页面以获得正确的值之后。
但是在重新加载之后,即使我的文件包含了新值,似乎常量仍然定义为旧值。
如果我在标题(Location)前放一个sleep,一切都可以正常工作。有没有不睡觉的解决办法,为什么?
下面是示例文件:
<?php
include_once 'toto.php';
if (isset($_GET['test'])) {
$file = "<?php const TOTO = '$_GET[test]'; ?>";
file_put_contents('toto.php', $file);
// sleep(3);
header('Location: index.php');
exit;
}
echo TOTO;
?>
我尝试将file_put_contents替换为fopen+fwrite+fflush+fclose,但没有成功。
以上代码对我来说运行良好。
你的index.php包含什么?
概念打破
常量的概念是在整个应用程序中它的值不会改变。你违背了常量的原则。
安全
另外,由于常量是通过用户输入定义的,并写入到文件中,因此我们可以很容易地用任何恶意代码劫持您的服务器。即:
http://localhost/index.php?test=42%27;eval($_GET[%27hack%27]);%3F>
然后我们可以在查询字符串后面添加任何我们想要执行的内容。
http://localhost/index.php?hack=echo%20shell_exec(%27cat%20%2Fetc%2Fpasswd%27)
中提琴,我们有你的/etc/passwd
文件。从那里,我们可以拿到你的/etc/shadow
文件然后劫持你的整个服务器。我们可以创建更多的后门到您的服务器-几乎做任何到您的服务器通过传递我们的命令hack
查询字符串参数。
修复
修改你的脚本,使它不会打破这个概念,或者你没有竞争条件写入新的值到文件和读取,考虑使用cookie或会话(两者都是唯一的客户端;cookie可以被客户端编辑,而会话通常不能(会话ID可以,但是绑定到会话ID的值不能)。
<?php
session_start();
include_once 'toto.php'; //or put session_start(); at the top of this file
if (isset($_GET['test'])) {
$_SESSION['TOTO'] = $_GET['test']; //Do some sanitation here since it's user input.
header('Location: index.php');
exit;
}
现在要阅读这个,只需使用$_SESSION['TOTO'];
。
但是,既然你已经提到这应该是一个全局配置(即:贯穿整个应用程序和所有用户),那么使用ini文件或数据库
你可以试着把这段代码-
<?php
include_once 'toto.php';
if (isset($_GET['test'])) {
$file = "<?php const TOTO = '$_GET[test]'; ?>";
if (file_put_contents('toto.php', $file)) {
// sleep(3);
header('Location: index.php');
exit;
}
}
echo TOTO;
?>
在这段代码中,只有当常量被正确写入文件时,头函数才会被调用。
您的问题也可能发生,因为在写toto.php之前页面被重定向。