2009-03-19 43 views
5

Tôi đang làm việc trên một dự án php và tôi muốn chạy mã được lấy từ cơ sở dữ liệu MySQL. Không có cơ hội mã không an toàn được tiêm, vì vậy điều duy nhất tôi lo lắng là biểu diễn. Tôi có nên sử dụng eval() vì vậy tôi có thể trực tiếp chạy mã, hoặc phân tích nó để call_user_func() chạy nó thay thế? Ví dụ, nếu mã tôi tìm nạp là "myfunc (1,2,3); anotherFunc (3,2,1);", ví dụ:
Tôi có thể eval() trực tiếp để chạy mã.Tôi có nên sử dụng eval() hoặc call_user_func() không?

Nhưng đối với call_user_func(), tôi phải phân tích chuỗi để có thể chạy chuỗi đó. Vì vậy, đó là chức năng tốt hơn để sử dụng trong trường hợp này?

+0

Xin lỗi về bản chỉnh sửa, nhưng tôi có ý tưởng như vậy bất cứ khi nào tôi thấy rằng KHÔNG CÓ CHANCE của một cái gì đó :) Hãy xóa nó đi, nếu bạn cảm thấy nó không nên ở đó. –

+0

Xin lỗi, nhưng nó không vui và cũng không mang tính hướng dẫn. Chỉ đơn thuần là lạm dụng các đặc quyền [IMHO]. – soulmerge

+0

Không có cơ hội nào vì tôi là người duy nhất có quyền ghi vào cơ sở dữ liệu mà nó gọi. – Drahcir

Trả lời

2

Theo nguyên tắc chung, tôi luôn cố gắng tránh xa eval() càng tốt. Trường hợp này, tuy nhiên, trông giống như một ứng cử viên tốt cho nó.

Bạn nói "Không có khả năng mã không an toàn được tiêm", do đó, câu hỏi lớn là: có cơ hội mã không hoạt động trong cơ sở dữ liệu không?

Nếu không, eval() là giải pháp, nhưng nếu có thì phân tích cú pháp và ghi nhật ký lỗi/etc đúng cách có thể là đặt cược an toàn hơn. (tôi tin rằng việc sử dụng call_user_func_array() nhanh hơn về mặt lý thuyết, vì vậy mọi chi phí phân tích cú pháp có thể trở nên không đáng kể)

1

Tôi nghĩ rằng phân tích cú pháp sẽ thêm phí, nhưng cách duy nhất bạn có thể chắc chắn là chạy thử nghiệm. Hãy thử cả hai cách với các chức năng khác nhau và xem kết quả của bạn là gì. Sử dụng mã đại diện cho những gì bạn mong muốn lưu trữ.

Chúc may mắn!

1

Sử dụng eval(). Bất cứ điều gì khác không đáng để nỗ lực - họ sẽ không có bất kỳ tác dụng phụ tích cực nào.

1

Bạn có thể muốn xem xét phần mở rộng runkit, có thể thực thi php trong hộp cát không ảnh hưởng đến mã đang chạy.

Nếu mã được giả sử là có hiệu lực cho mã đang chạy của bạn, hãy truy cập eval().

4

Lưu trữ PHP trong cơ sở dữ liệu là mùi thiết kế xấu; mặc dù trong trường hợp này bạn khá chắc chắn nó không bao giờ có thể chứa mã không an toàn, nó luôn luôn là tốt để giảm thiểu số lượng các giả định hoặc phòng thủ như bạn phải thực hiện. Nếu bạn lưu trữ mã PHP trong cơ sở dữ liệu, thì một cuộc tấn công mà kẻ tấn công truy cập vào cơ sở dữ liệu của bạn nhanh chóng trở nên nghiêm trọng hơn nhiều, biến thành một cuộc tấn công trong đó kẻ tấn công có thể chạy mã tùy ý! Tôi biết rằng có cơ sở dữ liệu của bạn bị xâm phạm như thế này là rất khó xảy ra, nhưng dù sao nó là thực hành bảo mật tốt không để cho ngay cả một tình huống không chắc chắn thỏa hiệp hệ thống của bạn nhiều hơn nó cần.

Many people agree rằng eval() nên luôn luôn, không có ngoại lệ, tránh được trong mã PHP. Luôn luôn có một sự thay thế. Tuy nhiên, trong trường hợp này, tôi nghĩ rằng tôi sẽ phải nói rằng việc sử dụng eval() sẽ là giải pháp tốt nhất cho bạn, bởi vì bạn đã lưu trữ mã PHP trong DB, vì vậy việc sử dụng eval() sẽ không để tăng thêm rủi ro của bạn hơn thế.

Tôi sẽ, tuy nhiên, khuyên

  1. Bạn cố gắng để xác thực mã trước khi bạn eval() nó, bằng cách bảo thủ trong những gì bạn cho phép. Giả sử rằng bằng cách nào đó kẻ tấn công vào cơ sở dữ liệu của bạn thậm chí nghĩ rằng điều đó là không thể.
  2. Bạn ít nhất phải suy nghĩ nghiêm túc để viết lại ứng dụng của mình để mã PHP không được lưu trữ trong cơ sở dữ liệu. Nếu bạn đang lưu trữ các cấu trúc dữ liệu phức tạp, hãy nghĩ về một cái gì đó như JSON hoặc thậm chí là XML. Các trình phân tích cú pháp an toàn tồn tại cho chúng.

Tôi xin lỗi nếu câu trả lời này có vẻ phản ứng một chút; Tôi chỉ cảm thấy điều này là rất quan trọng.

0

Bạn nên bao bọc mã bạn sắp chạy trong khối thử/nắm bắt, trong trường hợp có lỗi (mặc dù bạn đã nói sẽ không có, có khả năng và đó là phương pháp hay nhất)

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