Saya memiliki situasi dengan beberapa kode di mana eval()
muncul sebagai solusi yang mungkin. Sekarang saya belum pernah menggunakan eval()
sebelumnya tetapi, saya telah menemukan banyak informasi tentang potensi bahaya yang dapat ditimbulkannya. Yang mengatakan, saya sangat khawatir menggunakannya.
Situasi saya adalah saya mendapat input dari pengguna:
datamap = raw_input('Provide some data here: ')
Di mana datamap
perlu kamus. Saya mencari-cari dan menemukan bahwa ini eval()
bisa berhasil. Saya berpikir bahwa saya mungkin dapat memeriksa jenis input sebelum mencoba menggunakan data dan itu akan menjadi tindakan pencegahan keamanan yang layak.
datamap = eval(raw_input('Provide some data here: ')
if not isinstance(datamap, dict):
return
Saya membaca dokumen dan masih belum jelas apakah ini aman atau tidak. Apakah evaluasi mengevaluasi data segera setelah dimasukkan atau setelah datamap
variabel dipanggil?
Apakah ast
modul .literal_eval()
satu-satunya opsi yang aman?
sumber
ast.literal_eval("1 & 1")
akan melempar kesalahan tetapieval("1 & 1")
tidak akan.ast.literal_eval
untuk hal seperti itu (misalnya Anda dapat mengimplementasikan parser secara manual).ast.literal_eval()
hanya menganggap sebagian kecil sintaksis Python valid:Melewati
__import__('os').system('rm -rf /a-path-you-really-care-about')
menjadiast.literal_eval()
akan meningkatkan kesalahan, tapieval()
dengan senang hati akan menghapus drive Anda.Karena sepertinya Anda hanya membiarkan pengguna memasukkan kamus biasa, gunakan
ast.literal_eval()
. Dengan aman melakukan apa yang Anda inginkan dan tidak lebih.sumber
eval: Ini sangat kuat, tetapi juga sangat berbahaya jika Anda menerima string untuk dievaluasi dari input yang tidak dipercaya. Misalkan string yang dievaluasi adalah "os.system ('rm -rf /')"? Ini benar-benar akan mulai menghapus semua file di komputer Anda.
ast.literal_eval: Aman mengevaluasi simpul ekspresi atau string yang berisi tampilan literal Python atau wadah. String atau node yang disediakan hanya dapat terdiri dari struktur literal Python berikut: string, byte, angka, tupel, daftar, dicts, set, boolean, Tidak ada, byte dan set.
Sintaksis:
Contoh:
Dalam kode di atas
().__class__.__bases__[0]
hanya objek itu sendiri. Sekarang kita instantiated semua subclass , di sinienter code here
tujuan utama kita adalah menemukan satu kelas bernama n dari itu.Kita perlu
code
objek danfunction
objek dari subclass instantiated. Ini adalah cara alternatifCPython
untuk mengakses subclass objek dan melampirkan sistem.Dari python 3.7 ast.literal_eval () sekarang lebih ketat. Penambahan dan pengurangan angka arbitrer tidak lagi diizinkan. tautan
sumber
ast.literal_eval("1+1")
tidak bekerja di python 3.7 dan seperti yang dikatakan sebelumnya, literal_eval harus dibatasi pada literal dari beberapa struktur data tersebut. Seharusnya tidak dapat mengurai operasi biner.KABOOM
kode Anda ? Ditemukan di sini:KABOOM
KABOOM
dijelaskan dengan baik di sini: nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlPython sangat bersemangat dalam evaluasinya, sehingga
eval(raw_input(...))
akan mengevaluasi input pengguna segera setelah hitseval
, terlepas dari apa yang Anda lakukan dengan data sesudahnya. Karena itu, ini tidak aman , terutama saat Andaeval
input pengguna.Gunakan
ast.literal_eval
.Sebagai contoh, memasukkan ini pada prompt akan sangat, sangat buruk bagi Anda:
sumber
Jika yang Anda butuhkan adalah kamus yang disediakan pengguna, kemungkinan solusi yang lebih baik adalah
json.loads
. Keterbatasan utama adalah bahwa json dicts memerlukan kunci string. Anda juga hanya dapat memberikan data literal, tetapi itu juga berlaku untukliteral_eval
.sumber
Saya terjebak dengan
ast.literal_eval()
. Saya mencoba di IntelliJ IDEA debugger, dan terus kembaliNone
pada output debugger.Tapi kemudian ketika saya menetapkan outputnya ke variabel dan mencetaknya dalam kode. Itu bekerja dengan baik. Contoh kode berbagi:
Versi python-nya 3.6.
sumber