2008-11-27 29 views
21

Tôi muốn thực thi một tập lệnh php từ php sẽ sử dụng các hằng số khác nhau và các phiên bản khác nhau của các lớp đã được xác định.Có cách nào để thực thi mã php trong một hộp cát từ trong php

Có php_module sandbox nơi mà tôi có thể chỉ:

sandbox('script.php'); // run in a new php environment 

thay vì

include('script.php'); // run in the same environment 

Hoặc là proc_open() lựa chọn duy nhất?

PS: Tập lệnh không thể truy cập được qua web, vì vậy fopen ('http://host/script.php') không phải là một tùy chọn.

Trả lời

10

runkit, nhưng bạn có thể thấy đơn giản chỉ cần gọi tập lệnh qua dòng lệnh (Sử dụng shell_exec), nếu bạn không cần bất kỳ tương tác nào giữa quy trình chính và con.

+2

Giới thiệu về runkit; nó không có vẻ như sandbox tốt bằng cách mô tả, hoặc tôi có lẽ nên nói dễ dàng. Bạn có thể cấm các chức năng, nhưng tôi muốn cấm TẤT CẢ những người trong danh sách được cung cấp. Nếu người dùng cần một chức năng tôi có thể đánh giá sự an toàn của nó bằng tay theo yêu cầu. Dường như cách duy nhất là viết một thông dịch viên tùy chỉnh. Nếu tốc độ là một vấn đề bạn có thể làm cho nó chuyển đổi AST của nó thành PHP hoặc một ngôn ngữ khác, đây thực sự là những gì tôi sẽ làm bây giờ vì tôi không thể tìm thấy một giải pháp đã sẵn sàng. Chúc mừng! Ps. Có, tôi thấy rằng Q này là cũ. Ds. – Frank

+0

Vâng .. Chúc may mắn tìm kiếm một cái gì đó có thể phân tích PHP thành một AST;) Tôi đồng ý với điểm của bạn mặc dù. – troelskn

+0

FYI runkit dường như bị bỏ rơi và có thể bạn sẽ muốn biên dịch phiên bản CVS hoặc một trong các phiên bản được vá (http://github.com/tricky/runkit) nếu bạn muốn chạy nó trên phiên bản PHP hiện đại – Eli

2

Ngoài ra, bạn nên nhìn vào backtick operator:

$sOutput = `php script_to_run.php`; 

này sẽ cho phép bạn kiểm tra đầu ra từ kịch bản mà bạn đang chạy. Tuy nhiên, lưu ý rằng kịch bản sẽ được chạy với các đặc quyền bạn có, nhưng bạn có thể phá vỡ điều này bằng cách sử dụng sudo trên Linux.

Phương pháp này cũng giả định rằng bạn đã cài đặt CLI PHP, không phải lúc nào cũng như vậy.

1

Runkit_Sandbox - bạn có thể nhận được nó để làm việc, đó là một phần mở rộng PHP. Tôi sẽ nói đường đi.

Nhưng bạn có thể cần tự tạo "hộp cát", ví dụ: bằng cách đặt lại trạng thái biến toàn cầu của các superglobals bạn sử dụng.

class SandboxState 
{ 
    private $members = array('_GET', '_POST'); 
    private $store = array(); 
    public function save() { 
     foreach($members as $name) { 
      $this->store[$name] = $$name; 
      $$name = NULL; 
     } 
    } 
    public function restore() { 
     foreach($members as $name) { 
      $$name = $this->store[$name]; 
      $this->store[$name] = NULL; 
     } 

    } 
} 

Cách sử dụng:

$state = new SanddboxState(); 
$state->save(); 

// compile your get/post request by setting the superglobals 
$_POST['submit'] = 'submit'; 
... 

// execute your script: 
$exec = function() { 
    include(func_get_arg(0))); 
}; 
$exec('script.php'); 

// check the outcome. 
... 

// restore your own global state: 
$state->restore(); 
0

tôi biết không phải là 100% chủ đề của nó liên quan, nhưng có lẽ có ích cho ai đó n__n

function require_sandbox($__file,$__params=null,$__output=true) { 

    /* original from http://stackoverflow.com/a/3850454/209797 */ 

    if($__params and is_array($__params)) 
    extract($__params); 

    ob_start(); 
    $__returned=require $__file; 
    $__contents=ob_get_contents(); 
    ob_end_clean(); 

    if($__output) 
    echo $__contents; 
    else 
    return $__returned; 

}; 
+0

nó không hoạt động nếu $ __ tập tin cố gắng xác định hằng số đã được xác định. nó cũng có thể phá vỡ các biến toàn cầu nếu tập tin $ __ sử dụng từ khóa toàn cầu hoặc mảng $ GLOBALS để tham chiếu các biến trong phạm vi toàn cục. – DrLightman

+0

i cập nhật mã, thử ngay: D, nó rất hữu ích cho tôi: D có thể không hoàn hảo, nhưng rất hữu ích cho tôi để yêu cầu một số tập tin php người tạo vars trong quá trình thực hiện của họ mà tôi không muốn trong phạm vi toàn cầu: D – AgelessEssence

1

tôi đã phát triển một lớp sandbox BSD cấp phép cho rất này mục đích. Nó sử dụng thư viện PHPParser để phân tích mã hộp cát, kiểm tra nó với các danh sách trắng và danh sách đen có thể cấu hình người dùng và có một loạt các tùy chọn cấu hình cùng với các thiết lập mặc định sane. Đối với nhu cầu của bạn, bạn có thể dễ dàng xác định lại các lớp được gọi là trong mã hộp cát của bạn và định tuyến chúng đến các lớp khác nhau.

Dự án cũng bao gồm bộ công cụ hộp cát (chỉ sử dụng trên máy cục bộ của bạn!) Có thể được sử dụng để thử nghiệm với cài đặt hộp cát và tài liệu hướng dẫn sử dụng và API đầy đủ.

https://github.com/fieryprophet/php-sandbox

+0

Có cách nào để sử dụng lớp học của bạn mà không cài đặt nó thông qua nhà soạn nhạc. Tôi không muốn cài đặt nó trên máy chủ trực tiếp. Chỉ cần sử dụng các lớp học đơn giản? –

1

Plugin động chức năng thực hiện cho phép các tập tin được tải và chức năng để thực hiện bất cứ điều gì nó muốn, tuy nhiên nó chỉ có thể lấy và trở biến có thể được json_encode 'ed.

function proxyExternalFunction($fileName, $functionName, $args, $setupStatements = '') { 
    $output = array(); 
    $command = $setupStatements.";include('".addslashes($fileName)."');echo json_encode(".$functionName."("; 
    foreach ($args as $arg) { 
    $command .= "json_decode('".json_encode($arg)."',true),"; 
    } 
    if (count($args) > 0) { 
    $command[strlen($command)-1] = ")";//end of $functionName 
    } 
    $command .= ");";//end of json_encode 
    $command = "php -r ".escapeshellarg($command); 

    exec($command, $output); 
    $output = json_decode($output,true); 
} 

mã bên ngoài là hoàn toàn sandboxed và bạn có thể áp dụng bất kỳ hạn chế cho phép bạn muốn bằng cách làm sudo -u restricedUser php -r ....

Các vấn đề liên quan