推迟从一个PHP脚本编译到另一个

时间:2015-08-18 20:49:33

标签: php

我想要实现的目标

  1. 我的php脚本正在运行:http://execute.tld
  2. 在运行时我想从其他网站获取内容(也是脚本):http://noexecution.tld没有执行(编译)但是推迟执行
  3. 现在我想在http://noexecution.tld
  4. 上执行http://execute.tld的内容
      

    这有点像抓取全局脚本片段并在将它们放在不同的服务器上后进行编译。

    文件

    main.php | http://execute.tld/main.php

    <?php
    $var = 'main.php';
    file_put_contents("local_sub.php", file_get_contents("http://noexecution.tld/sub.php") );
    include "local_sub.php";
    echo $var;
    ?>
    

    sub.php | http://noexecution.tld/sub.php

    sub.php | line 1 notcompiled<br>
    <?php $var = 'sub.php | line 2 compiled later<br>'; ?>
    sub.php | line 3 notcompiled<br>
    

    运行main.php后的结果

    sub.php | line 1 notcompiled
    sub.php | line 3 notcompiled
    main.php
    

    通缉结果

    sub.php | line 1 notcompiled
    sub.php | line 3 notcompiled
    line 2 compiled later
    

    我自己的解决方法

    我自己的解决方法是简单地将扩展名从 sub.php切换到sub.whatever 并将其“动态”重命名。

    文件

    main.php | http://execute.tld/main.php

    源代码相同但已更改

    file_get_contents(“http://noexecution.tld/sub php ”)

    的file_get_contents( “http://noexecution.tld/sub。的 DontCompileAsPhp ”)。

    <?php
    $var = 'main.php';
    file_put_contents("local_sub.php", file_get_contents("http://noexecution.tld/sub.DontCompileAsPhp"));
    include "local_sub.php";
    echo $var;
    ?>
    

    sub.DontCompileAsPhp | http://noexecution.tld/sub.DontCompileAsPhp

    源代码是相同的但没有php扩展,它也不会被编译为php。

    sub.php | line 1 notcompiled<br>
    <?php $var = 'sub.php | line 2 compiled later<br>'; ?>
    sub.php | line 3 notcompiled<br>
    

    运行main.php后的结果(完全符合我的需要)

    sub.php | line 1 notcompiled
    sub.php | line 3 notcompiled
    line 2 compiled later
    

    为什么我对我的解决方法不满意?

    我希望有一种干净的方式来推迟编译,而无需使用扩展程序......

    我也尝试过的事情

    1. __halt_compiler(); [...]
    2. ob_start(); [...]
    3. 非常欢迎任何帮助 - 提前预约 |顺便说一句:这是我的第一个问题

5 个答案:

答案 0 :(得分:7)

正如@Dagon在评论中指出的那样,当您向全世界打开脚本时,您将在应用程序中创建一个巨大的安全漏洞。

由于你想要实现的是在多个应用程序/服务器之间共享脚本,我至少可以通过两种方式来思考:

  • 使用安全连接直接访问主服务器,例如通过SSH访问主服务器,然后从那里获取脚本。
  • 使用Git存储库保留所有共享脚本,并自动将其部署到您的服务器。

第二个是更好的选择,包括安全性和性能。这样做你不需要在执行期间访问另一台服务器来获取脚本,并且你将拥有所有共享脚本的本地副本。

您还可以使用依赖项管理器(如Composer(Mr. Narendra Modi, The Prime Minister of Bharat (a.k.a. India )))轻松地将脚本添加到新应用程序中。

答案 1 :(得分:5)

首先,如果我错了,请纠正我,php是解释语言而不是编译语言。

对于你的问题,我强烈建议你将代码放在明显的。确实,黑客需要知道文件的确切文件名才能访问它,但仍然存在我不会采取的安全风险。因此,我能想到的最快,最简单的解决方案是:

    使用.htaccess文件
  1. 保护noexecution.tld/scripts中的脚本文件夹,该文件应如下所示:

    AuthType Basic
    AuthName "Do you have security clearance for this ?"
    AuthUserFile /path/to/.htpasswd
    Require valid-user
    

    和.htpasswd应该是这样的(对于admin:admin身份验证):

    admin:$apr1$kO7YWurq$QHrgAbwXAyNZJfBd/gEc71
    

    您可以使用this link为任何用户生成.htpasswd文件:您喜欢的密码

  2. 您可以继续更改您的php脚本扩展程序,或者将此附加到您的.htaccess ,以便将基础文件夹中的php文件视为二进制文件文件:

    AddType application/octet-stream .php
    
  3. 至于如何在noexecution.tld/scripts上从PHP execution.tld/*.php访问文件,您需要使用curl设置基本身份验证。如果您不知道如何实现,请查看this tutorial

答案 2 :(得分:4)

您提出的“解决方法”是唯一的解决方案,尽管有一些变体。你正在做的并不是“延迟执行脚本”,你只是在(可能是公共的)网页上提供一些恰好是PHP源代码的文本。

托管该文本文件的服务器无法控制您下载时所执行的操作,因此稍后执行该代码的代码基本上无关紧要(就像您保存到的临时文件的名称一样 - include不检查文件扩展名。)

从这个角度来看,有几种基本相同的方法:

  • 不要使用.php结束文件名,因此服务器不会尝试执行它
  • 不要在该服务器上安装PHP
  • 配置该服务器,或该vhost或该目录,而不是执行以.php结尾的文件

或者,当然,您可以编写一个PHP脚本来回显PHP源代码,而不仅仅是将代码放在文本文件中。如果代码以某种方式动态更改,这将更有意义,这将更接近于“延迟某些代码执行”的描述。

答案 3 :(得分:3)

您可以在noexecution.tld服务器上使用warpper脚本(例如download.php),该服务器提供您的php文件的明文,正如我在Update local php file from remote php file

所建议的那样
<?php
$file = $_SERVER['DOCUMENT_ROOT'] . $_GET['file'];

// @TODO: Add security check if file is of type php and below document root. Use realpath() to check this.
header("Content-Type: text/plain");
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
?>

这将被称为http://noexecition.tld/download.php?file=sub.php

但是:您必须为此脚本添加安全预防措施,因为它会将任何文件传送到调用脚本,甚至是配置文件等敏感文件。

可能的检查:

  1. 仅提供.php文件供下载
  2. 仅允许下载特定文件夹中的文件,例如/下载的脚本
  3. 使用身份验证,至少需要像key = whatEverPassword
  4. 这样的必需get参数
  5. 使用带时间戳的哈希来允许在给定的时间段内访问文件
  6. 要有创意!

答案 4 :(得分:0)

导出源代码:

  • 在noexecution上写一个脚本,读取它作为参数获取的文件并输出源代码。
  • 保护它,以便只有execution.tld获取源代码。

要执行它,为什么要花费一些文件(到磁盘)的开销并在eval()时再次读取它 你必须从输入的最末端剥离开始(<?php)和结束(?>)标签,但这是一个简单的字符串操作......你可以在noexecution的输出脚本中做已经......

但也许更简单的解决方案是在服务器之间使用某种复制或文件共享。