Saya ingin menulis ke file berdasarkan apakah file itu sudah ada atau tidak, hanya menulis jika belum ada (dalam praktiknya, saya ingin terus mencoba file sampai saya menemukan file yang tidak ada).
Kode berikut menunjukkan cara di mana penyerang yang berpotensi dapat menyisipkan symlink, seperti yang disarankan dalam posting ini di antara pengujian untuk file dan file yang sedang ditulis. Jika kode dijalankan dengan izin yang cukup tinggi, ini dapat menimpa file arbitrer.
Apakah ada cara untuk mengatasi masalah ini?
import os
import errno
file_to_be_attacked = 'important_file'
with open(file_to_be_attacked, 'w') as f:
f.write('Some important content!\n')
test_file = 'testfile'
try:
with open(test_file) as f: pass
except IOError, e:
# symlink created here
os.symlink(file_to_be_attacked, test_file)
if e.errno != errno.ENOENT:
raise
else:
with open(test_file, 'w') as f:
f.write('Hello, kthxbye!\n')
Jawaban:
Edit : Lihat juga jawaban Dave Jones : dari Python 3.3, Anda dapat menggunakan
x
flag toopen()
untuk menyediakan fungsi ini.Jawaban asli di bawah
Ya, tetapi tidak menggunakan
open()
panggilan standar Python . Anda harus menggunakanos.open()
sebagai gantinya, yang memungkinkan Anda menentukan bendera ke kode C yang mendasarinya.Secara khusus, Anda ingin menggunakan
O_CREAT | O_EXCL
. Dari halaman manual untuk diopen(2)
bawahO_EXCL
pada sistem Unix saya:Jadi memang tidak sempurna, tapi AFAIK paling dekat bisa Anda hindari untuk menghindari kondisi balapan ini.
Sunting: aturan penggunaan lain
os.open()
daripadaopen()
tetap berlaku. Secara khusus, jika Anda ingin menggunakan deskriptor file yang dikembalikan untuk membaca atau menulis, Anda memerlukan salah satu tandaO_RDONLY
,O_WRONLY
atauO_RDWR
juga.Semua
O_*
bendera ada dios
modul Python , jadi Anda harusimport os
dan menggunakanos.O_CREAT
dll.Contoh:
sumber
Sebagai referensi, Python 3.3 mengimplementasikan
'x'
mode baru dalamopen()
fungsi untuk mencakup kasus penggunaan ini (hanya buat, gagal jika file ada). Perhatikan bahwa'x'
mode ditentukan sendiri. Menggunakan'wx'
hasil dalam aValueError
sebagai'w'
redundan (satu-satunya hal yang dapat Anda lakukan jika panggilan berhasil adalah tetap menulis ke file; itu tidak akan ada jika panggilan berhasil):Untuk Python 3.2 dan yang lebih lama (termasuk Python 2.x), lihat jawaban yang diterima .
sumber
Python 3.2 (r32:88445, Feb 20 2011, 21:30:00)
[MSC v.1500 64 bit (AMD64)] on win32
>>> open("c:/temp/foo.csv","wx")
ValueError: invalid mode: 'wx'
ValueError: must have exactly one of create/read/write/append mode
Kode ini akan dengan mudah membuat FILE jika tidak ada.
sumber
if
pernyataan, kode ini akan mengosongkan file.