Ich möchte in eine Datei schreiben, basierend darauf, ob diese Datei bereits vorhanden ist oder nicht, und nur schreiben, wenn sie noch nicht vorhanden ist (in der Praxis möchte ich weiterhin versuchen, Dateien zu finden, bis ich eine finde, die nicht vorhanden ist).
Der folgende Code zeigt eine Möglichkeit, wie ein potenzieller Angreifer einen Symlink einfügen kann, wie in diesem Beitrag zwischen einem Test für die Datei und der zu schreibenden Datei vorgeschlagen. Wenn der Code mit ausreichend hohen Berechtigungen ausgeführt wird, kann dies eine beliebige Datei überschreiben.
Gibt es eine Möglichkeit, dieses Problem zu lösen?
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')
Antworten:
Bearbeiten : Siehe auch Dave Jones 'Antwort : Ab Python 3.3 können Sie das
x
Flag verwendenopen()
, um diese Funktion bereitzustellen.Ursprüngliche Antwort unten
Ja, aber nicht mit Pythons Standardaufruf
open()
. Sie müssenos.open()
stattdessen verwenden, um Flags für den zugrunde liegenden C-Code anzugeben.Insbesondere möchten Sie verwenden
O_CREAT | O_EXCL
. Von der Manpage füropen(2)
unterO_EXCL
auf meinem Unix-System:Es ist also nicht perfekt, aber AFAIK ist das Beste, was Sie tun können, um diese Rennbedingung zu vermeiden.
Bearbeiten: Die anderen Regeln für die Verwendung
os.open()
anstelle vonopen()
weiterhin gelten. Insbesondere dann , wenn Sie den zurück Dateideskriptor zum Lesen oder Schreiben verwenden wollen, müssen Sie eine der benötigenO_RDONLY
,O_WRONLY
oderO_RDWR
Fahnen als auch.Alle
O_*
Flags befinden sich im Python-os
Modul, Sie müssen also usw.import os
verwendenos.O_CREAT
.Beispiel:
quelle
Als Referenz implementiert Python 3.3 einen neuen
'x'
Modus in deropen()
Funktion, um diesen Anwendungsfall abzudecken (nur erstellen, fehlschlagen, wenn eine Datei vorhanden ist). Beachten Sie, dass der'x'
Modus eigenständig angegeben wird. Verwenden von'wx'
Ergebnissen in aValueError
als'w'
redundant (das einzige, was Sie tun können, wenn der Aufruf erfolgreich ist, ist das Schreiben in die Datei; es kann nicht existiert haben, wenn der Aufruf erfolgreich ist):Informationen zu Python 3.2 und niedriger (einschließlich Python 2.x) finden Sie in der akzeptierten Antwort .
quelle
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
Dieser Code erstellt leicht eine DATEI, wenn keine vorhanden ist.
quelle
if
Anweisung eine Datei erstellt und in diese schreibt, wird die Datei durch diesen Code ausgeblendet.