2013-06-04 23 views
5

Tôi đang viết một ứng dụng và tôi muốn người dùng có thể nhập tệp python cho các trường hợp góc. Trong đầu của tôi cách tốt nhất tôi có thể nghĩ đến việc này là lưu tệp của họ vào đĩa và lưu vị trí vào DB sau đó nhập động bằng cách sử dụng __import__() và sau đó thực thi nó. Phần đầu tiên của câu hỏi của tôi là: đây có phải là cách tốt nhất để làm điều này không?Đọc động trong tệp python và thực hiện nó một cách an toàn

Ngoài ra, điều này sẽ trả về một số vấn đề bảo mật khá lớn. Có cách nào để chạy mô-đun của họ theo hạn chế không? Để không để cho nó nhìn thấy hệ thống tập tin hoặc bất cứ điều gì?

Edit:

Việc thực hiện của python sẽ để lấy dữ liệu từ một dịch vụ phụ trợ nằm ngoài phạm vi "bình thường", Vì vậy, nó sẽ không là một ứng dụng đầy đủ. Nó chỉ có thể là một định nghĩa của một giao thức tùy chỉnh.

+2

http://wiki.python.org/moin/SandboxedPython ... Tôi sẽ đặt câu trả lời đó là ... nhưng thực sự chỉ đọc bài viết này ... –

Trả lời

3

Bạn có thể sử dụng kết hợp các nội trang compileexec để thực thi trong bộ nhớ. Nhược điểm là bạn không nhận được dòng nguồn trong tracebacks.

Không có nhiều hy vọng về bảo mật. Ngay cả khi bạn đặt các bộ lọc hạn chế một cách lố bịch, như hạn chế mọi thứ thành một biểu thức duy nhất và loại bỏ hầu hết các chức năng tích hợp sẵn, arbitrary code can be executed. Nghiêm cấm truy cập hệ thống tập tin, hoặc truy cập vào các tài nguyên hệ điều hành khác, cũng khó trong Python, vì mã sẽ chạy trong cùng một tiến trình. Một quá trình con với những hạn chế nghiêm trọng (chroot tù, ulimit, v.v.) là một khả năng, nhưng đó không chỉ là nhiều công việc, nó cũng loại trừ hầu hết các phương tiện tương tác với ứng dụng máy chủ.

Nếu ứng dụng của bạn chạy cục bộ và có cùng quyền như tài khoản của người dùng, tốt nhất là bạn không nên lo lắng và cung cấp cho họ nhiều quyền lực hơn. sẽ làm cho nhiệm vụ (bất kể nó là gì) khó hơn/khó chịu hơn. Mặt khác, nếu mã sẽ thực thi trên máy chủ hoặc thứ gì đó, hãy quên khoảng chạy mã đó trong cùng một quy trình.

+0

Tôi suy nghĩ tôi có thể sinh ra một thể hiện sandbox của jvm và chạy jython trong đó. Bằng cách đó, tôi có thể lấy mã người dùng nhiều hơn chỉ là python. Điều đó có ý nghĩa? Tôi cũng đã gặp [pysandbox] (https://github.com/haypo/pysandbox), nhưng tôi không chắc là nó hợp pháp như thế nào. –

+0

@ sir_charles804 Âm thanh khả thi. Tôi sẽ mệt mỏi khi lăn cái gì đó như thế này, mặc dù vậy, nhiều cơ hội để vặn lên. Điều đó nói rằng, tôi cũng cẩn thận kiểm tra của bất kỳ dự án bên thứ ba làm điều này (chẳng hạn như 'pysandbox'). – delnan

+0

Tôi đồng ý. Tôi nghĩ rằng nếu tôi làm điều này nó sẽ được với một máy ảo. Bằng cách đó tôi tin tưởng các container.Tôi đã không quyết định rằng đây là cách tôi sẽ cho phép người dùng xác định các kết nối cho các trường hợp góc hoặc chưa, nhưng đầu vào của bạn là rất hữu ích. Cảm ơn! –

0

Bạn có thể xem xét phương pháp

class _DynamicModule(object): 
    def __init__(self, name): 
     self._name = name 

    def load(self, code): 
     execdict = {'__builtins__': __builtins__} 
     exec compile(code, '<string>', 'exec') in execdict 
     for key in execdict: 
      if not key.startswith('_'): 
       if not isinstance(execdict[key], str): 
        execdict[key].__module__ = self._name 
       setattr(self, key, execdict[key]) 
     return self 

import sys 
sys.modules['dummy_modules'] = _DynamicModule('dummy_modules').load('print ("!")') 

này vẫn có mối quan tâm an ninh khá lớn sau.

1

bạn có thể làm một vài điều để hạn chế quyền hạn (xem nhận xét của tôi về OP)

nhưng thực sự hai xu của tôi ... chỉ cần cung cấp cho mỗi người dùng máy ảo riêng của họ (có thể AWS?) ... như vậy họ cant vít lên nhiều ... và bạn luôn có thể khởi động lại ...

một cách tiếp cận phức tạp hơn (nhưng được cho là lạnh hơn) sẽ sử dụng lex/yacc (trong python PLY) và xác định ngôn ngữ của bạn (có thể là một tập con giới hạn của python)

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