簡體   English   中英

禁用嵌入式Python中的內置模塊導入

[英]Disable built-in module import in embedded Python

我在我的應用程序中嵌入了Python 3.6,我想在腳本中禁用import命令以防止用戶導入任何python內置庫。 我只想使用語言本身和我自己的C ++定義模塊。

Py_SetProgramName (L"Example");
Py_Initialize ();
PyObject* mainModule = PyImport_AddModule ("__main__");
PyObject* globals = PyModule_GetDict (mainModule);

// This should work
std::string script1 = "print ('example')";
PyRun_String (script1.c_str (), Py_file_input, globals, nullptr);

// This should not work
std::string script2 = "import random\n"
                      "print (random.randint (1, 10))\n";
PyRun_String (script2.c_str (), Py_file_input, globals, nullptr);

Py_Finalize ();

你知道怎么做到這一點嗎?

Python有很長的歷史,無法創建一個安全的沙箱(請參閱我如何在純Python中沙盒Python?作為起點,然后深入探討舊的python-dev討論,如果您願意的話)。 以下是我認為最好的兩種選擇。

預掃描代碼

在執行任何操作之前,請掃描代碼。 您可以使用AST模塊在Python中執行此操作,然后遍歷樹,或者可以通過更簡單的文本搜索獲得足夠的效果。 這可能適用於您的場景,因為您具有受限的用例 - 它不會推廣到真正任意的代碼。

在您的情況下,您正在尋找的是任何import語句(簡單),以及任何頂級變量(例如,在abc您關心某個給定a a和可能的ab )並非“已批准”。 這將使您在運行之前對任何不干凈的代碼失敗。

這里的挑戰是即使是模糊的代碼也會繞過你的檢查。 例如,以下是一些導入模塊的方法,這些模塊給定了import的基本掃描找不到的其他模塊或全局變量。 您可能希望使用__double_underscores__和某些類型的成員限制對__builtins__ __double_underscores__globals ,某些/大多數/所有名稱的直接訪問。 在AST中,這些將不可避免地顯示為頂級變量讀取或屬性訪問。

getattr(__builtins__, '__imp'+'ort__')('other_module')

globals()['__imp'+'ort__']('other_module')

module.__loader__.__class__(
    "other_module",
    module.__loader__.path + '/../other_module.py'
).load_module()

(我希望有點不用說,這是一個不可能的挑戰,為什么這種沙盒方法從未完全成功。但它可能已經足夠好了,具體取決於您的特定威脅模型。)

運行時審核

如果您可以編譯自己的Python運行時,可以考慮使用(當前草案) PEP 551鈎子。 (免責聲明:我是本PEP的作者。)針對最新的3.73.6版本提供了草案實施。

實質上,這將允許您為Python中的一系列事件添加鈎子並確定如何響應。 例如,您可以監聽所有import事件,並根據要導入的模塊確定是在運行時允許還是失敗,或者監聽compile事件以管理所有運行時編譯。 您可以使用Python代碼(使用sys.addaudithook )或C代碼(使用PySys_AddAuditHook )執行此操作。

repo中的Programs / spython.c文件是一個相當徹底的C審計示例,而從Python執行它看起來更像是這樣(取自對此PEP的討論):

import sys

def prevent_bitly(event, args):
    if event == 'urllib.Request' and '://bit.ly/' in args[0]:
        print(f'WARNING: urlopen({args[0]}) blocked')
        raise RuntimeError('access to bit.ly is not allowed')

sys.addaudithook(prevent_bitly)

這種方法的缺點是您需要構建和分發自己的Python版本,而不是依賴於系統安裝。 但是,一般來說,如果您的應用程序依賴於嵌入,這是一個好主意,因為這意味着您不必強制用戶進入特定的系統配置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM