2012-03-30 38 views
6

Tôi đang viết một hệ thống cho một ứng dụng trình duyệt sẽ lưu trữ một số tập lệnh php cụ thể trong cơ sở dữ liệu và sau đó kéo chúng ra và thực thi chúng khi cần. Lúc đầu, tôi đã thử bằng cách sử dụng exec() và piping để php đầu ra của một kịch bản có các kịch bản ra khỏi cơ sở dữ liệu và in chúng. Điều này làm việc trong một trường hợp sử dụng, nhưng không phải tất cả, và cảm thấy giòn anyway, vì vậy tôi đang tìm kiếm một cách tốt hơn.Bao gồm từ luồng "php: // memory"

Tôi hiện đang cố thực hiện điều này thông qua việc sử dụng luồng tệp PHP trong bộ nhớ. Ví dụ:

$thing = <<<'TEST' 
<?php 

$thing = array(); 

print "Testing code in here."; 
var_dump($thing); 

?> 
TEST; 

$filename = "php://memory"; 

$fp = fopen($filename, "w+b"); 
fwrite($fp, $thing); 
//rewind($fp); 

fclose($fp); 

include "php://memory"; 

Tuy nhiên, không có gì được in khi tập lệnh được thực thi. Điều này có thể thực hiện được bằng cách này hay không, và nếu không, liệu có cách nào khác để làm điều này không? Tôi đang cố gắng tránh phải viết các tập tin tạm thời và đọc từ chúng, vì tôi chắc chắn rằng việc truy cập hệ thống tập tin sẽ làm chậm mọi thứ. Có một URL tôi có thể cung cấp để "bao gồm" để nó sẽ đọc dòng bộ nhớ như thể nó là một tập tin?

Tôi không nghĩ rằng eval() sẽ làm điều này, vì, nếu tôi nhớ chính xác, nó bị giới hạn ở một dòng.

Ngoài ra, vui lòng không trả lời "eval = include = hell". Người dùng không phải quản trị viên không có quyền truy cập để viết các tập lệnh được lưu trữ trong cơ sở dữ liệu, tôi biết rằng điều này cần được xử lý đặc biệt trong vòng đời của ứng dụng của tôi.

+0

My từ, tôi hoàn toàn sai. Eval làm việc cho nhiều hơn một dòng. Tôi thậm chí không thử nó lol ... giả sử rằng sẽ làm việc sau đó. Tuy nhiên, tôi vẫn tò mò về các luồng tệp được lưu trữ trong bộ nhớ, vì vậy nếu có ai có câu trả lời cho phần đó, tôi sẽ rất biết ơn. –

+0

Có lý do cụ thể nào khiến bạn không muốn tạo tệp không? Hệ thống tập tin là một cơ sở dữ liệu cho các tập tin. Và: OMG KHÔNG LÀM R THNG NGUY HIỂM. Nó không quan trọng nếu chỉ quản trị viên có thể ghi vào các tệp php này, ngay khi bạn có lỗi SQL injection hoặc ai đó quản lý để nhận/đoán/tiết lộ thông tin đăng nhập MySQL của bạn -> insta-remote-code-execution. – mensi

Trả lời

5

Bạn cần sử dụng stream_get_contents để đọc từ số php://memory stream. Bạn không thể bao gồm nó trực tiếp.

4

eval()include thực sự khá giống nhau. Vì vậy, eval() hoạt động với nhiều dòng - chỉ FYI. Tuy nhiên, tôi thích include ở đây, tôi luôn nghĩ rằng nó nhanh hơn. Có lẽ tôi sai, không có ý tưởng.

Tuy nhiên, tôi nghĩ bạn nên gỡ lỗi mã của mình, tôi không thấy lý do mỗi lần tại sao nó không hoạt động. Bạn có thể cần phải rewind con trỏ (bạn đã nhận xét rằng), nhưng những gì bạn nên kiểm tra trực tiếp là, that your PHP configuration allows to include URLs. Tôi biết rằng cài đặt đó ngăn không cho sử dụng các URI data://, vì vậy bạn có thể bật tính năng này.

Ngoài ra, bạn luôn có thể thử nếu PHP có thể mở bộ nhớ bằng cách sử dụng file_get_contents và bán phá giá. Điều này sẽ cung cấp cho bạn mã. Nếu không, bạn đã thực hiện một số sai lầm (ví dụ: không tua lại hoặc một cái gì đó tương tự).

Edit: Tôi đã không đến mà xa (demo):

<?php 
/** 
* Include from “php://memory” stream 
* @link https://stackoverflow.com/q/9944867/367456 
*/ 

$thing = <<<TEST 
<?php 
\$thing = array(); 
print "Testing code in here."; 
var_dump(\$thing); 
TEST; 

$filename = "php://memory"; 

$fp = fopen($filename, "w+b"); 
fwrite($fp, $thing); 
rewind($fp); 

var_dump(stream_get_contents($fp)); 

Đây là những gì tôi phát hiện ra:

  1. Bạn không nên đóng "File". php://memory là luồng khi đã đóng, luồng sẽ biến mất.
  2. Bạn cần truy cập số $fp dưới dạng luồng, điều này là không thể cho include ngoài hộp AFAIK.
  3. Sau đó, bạn sẽ cần phải tạo trình bao bọc luồng ánh xạ tài nguyên luồng tới tên tệp.
  4. Khi bạn đã thực hiện điều đó, bạn có thể bao gồm luồng bộ nhớ.
  5. Cài đặt PHP bạn cần kiểm tra. Có nhiều hơn một tài liệu tham khảo hướng dẫn sử dụng PHP.

Nó có thể được dễ dàng hơn để sử dụng dữ liệu URI (demo):

<?php 
/** 
* Include from “php://memory” stream 
* @link https://stackoverflow.com/q/9944867/367456 
*/ 

$thing = <<<TEST 
<?php 
\$thing = array(); 
print "Testing code in here."; 
var_dump(\$thing); 
TEST; 

include 'data://text/plain;,'. urlencode($thing); 

Xem cũng như: Include code from a PHP stream

+0

Điều này cho một lỗi biến không xác định. Để sửa lỗi, thay đổi 'var_dump ($ thing);' thành 'var_dump (\ $ thing);' –

+0

@ CláudioSilva: Đã sửa lỗi. Thx cho gợi ý. – hakre

0

Nếu có một cách để bao gồm từ php: // bộ nhớ thì đây là một lỗ hổng nghiêm trọng. Trong khi nó có nhiều công dụng, eval được sử dụng khá thường xuyên với các kỹ thuật mã hóa để che giấu mã độc.

(Mỗi công cụ là một vũ khí nếu bạn giữ nó đúng.)

Với những gì đã nói, ở đó (may mắn) không xuất hiện để được bất kỳ cách rõ ràng để bao gồm từ php: // nhớ

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