请比较以下代码:
1)
/file.php:
$newconn = new PDO('mysql:host=localhost;charset=utf8mb4;','username','password');
2)
../secrets.php:
$mysqlusername = 'username';
$mysqlpassword = 'password';
/file.php:
require_once('../secrets.php');
$newconn = new PDO('mysql:host=localhost;charset=utf8mb4;',$mysqlusername,$mysqlpassword);
3
../secrets.php:
function pdoconn(i) {
$mysqlusername = ['username1','username2'];
$mysqlpassword = ['password1','password2'];
$conn = new PDO('mysql:host=localhost;charset=utf8mb4;',$mysqlusername[i],$mysqlpassword[i]);
return $conn;
}
/file.php:
require_once('../secrets.php');
$newconn = pdoconn(0);
示例 1 是不可能的 - 生产服务器上的错误配置最终可能会向非预期方显示敏感参数。
示例 2 更好,但这些变量在整个应用程序中都可用,并且可以修改,这可能会导致错误。
示例 3 使事情变得非常有条理和可转移。
如果../secrets.php
改为使用全局变量,则可以修改为:
../secrets.php:
$mysqlusername = 'username';
$mysqlpassword = 'password';
function pdoconn() {
$conn = new
PDO('mysql:host=localhost;charset=utf8mb4;',$GLOBALS['mysqlusername'],$GLOBALS['mysqlpassword']);
return $conn;
}
我认为这以非常简洁的方式说明了为什么大多数时候全局没有意义。
概括:
至于使用全局变量的安全漏洞(以及为什么我在 PHP 中编写这些示例),在 PHP 4.2.0中有一个(当时)有争议的更改,其中 register_globals 被打开到关闭。我现在找不到任何文章,因为此更改是在 2002 年进行的,但我似乎确实记得它对当时的一些违规行为负责。直接从手册中复制,有一个非常清晰的易受攻击代码示例:
<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
$authorized = true;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
include "/highly/sensitive/data.php";
}
?>