PHP文件下载直接访问


PHP file downloads on direct visit

我非常清楚PHP是一种服务器端语言,因此不应该允许下载PHP文件。然而,在Chrome中直接访问PHP文件时,它会下载该文件的模糊版本,这是我想防止的。有没有办法阻止文件被送达?

代码如下
该系统在WordPress中运行得非常完美,但如果我打开Chrome(我想还有其他浏览器)并直接访问update.php文件,它就会下载。

值得注意的是,我试图回显HTML页面,但它扰乱了系统的工作方式。我希望有某种.htaccess技巧。

if (isset($_POST['action'])) {
  switch ($_POST['action']) {
    case 'version':
      echo '1.1';
      break;
    case 'info':
      $obj = new stdClass();
      $obj->slug = 'plugin.php';
      $obj->plugin_name = 'plugin.php';
      $obj->new_version = '1.1';
      $obj->requires = '3.0';
      $obj->tested = '3.3.1';
      $obj->downloaded = 12540;
      $obj->last_updated = '2012-01-12';
      $obj->sections = array(
        'description' => 'The new version of the Auto-Update plugin',
        'another_section' => 'This is another section',
        'changelog' => 'Some new features'
      );
      $obj->download_link = 'http://localhost/update.php';
      echo serialize($obj);
    case 'license':
      echo 'false';
      break;
  }
} else {
    header('Cache-Control: public');
    header('Content-Description: File Transfer');
    header('Content-Type: application/zip');
    readfile('update.zip');
}

如果您的代码没有接收到$_POST['action'],则在else的情况下将update.zip发送到浏览器。

当你不通过POST访问文件时,你看到的并不是模糊的PHP。相反,它将文件update.zip的内容发送到浏览器进行下载。但是,由于代码在头中没有提供文件名提示,因此它不是update.zip,而是看起来像一个与脚本同名的.php文件。

如果您希望update.zip看起来像一个zip文件,请在Content-Disposition输出标头中添加一个filename

header('Cache-Control: public');
header('Content-Description: File Transfer');
// Change to attachment disposition, with filename
header('Content-Disposition: attachment; filename=update.zip');
header('Content-Type: application/zip');
readfile('update.zip');

现在,如果根本不希望它发送update.zip,请从底部删除整个else {}块,并用之类的东西替换它

else {
  echo "You must supply an action...";
}

更新:仅限wp_autoupdate.php推荐访问

请参阅$_SERVER['HTTP_REFERRER'],但要知道其值可能会被伪造。这不能以100%的可靠性使用。

if (strpos($_SERVER['HTTP_REFERER'], 'wp_autoupdate.php') !== FALSE) {
  // Include all your exsiting code
}
else {
  // Don't do anything, or redirect somewhere else
  header("Location: /");
  exit();
}

为了实现100%的可靠性,您可能需要修改wp_autoupdate.php来设置一个会话变量,然后由update.php进行检查,以确保请求来自正确的位置。

您将内容类型设置为application/zip,在大多数浏览器中会提示下载。您是否有可能没有通过POST传递"操作",这就是它进入其他部分的原因?

我看到的另一件事是你没有

break;

在您的第二个开关/案例中。

      $obj->download_link = 'http://localhost/update.php';
      echo serialize($obj);
      break;  // <------ this is missing!
    case 'license':
      echo 'false';
      break;

你看过这篇文章吗:http://konstruktors.com/blog/wordpress/2538-automatic-updates-for-plugins-and-themes-hosted-outside-wordpress-extend/


关于限制除WordPress以外的所有人访问该文件,不知道你是否托管你的WordPress网站。如果这样做,您可以在.htaccess文件中限制对localhost或127.0.0.1的访问。如果它托管在WordPress.com上,你可以找到他们的IP或主机名并更改它。

<Files update.php>
    Order allow,deny
    Deny from all
    Allow from 127.0.0.1
</Files>