Je souhaite écrire dans un fichier en fonction du fait que ce fichier existe déjà ou non, en n'écrivant que s'il n'existe pas déjà (en pratique, je souhaite continuer à essayer des fichiers jusqu'à ce que j'en trouve un qui n'existe pas).
Le code suivant montre une manière dont un attaquant potentiel pourrait insérer un lien symbolique, comme suggéré dans cet article entre un test pour le fichier et le fichier en cours d'écriture. Si le code est exécuté avec des autorisations suffisamment élevées, cela pourrait écraser un fichier arbitraire.
Existe-t-il un moyen de résoudre ce problème?
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')
Réponses:
Edit : Voir aussi la réponse de Dave Jones : à partir de Python 3.3, vous pouvez utiliser l'
x
indicateuropen()
pour fournir cette fonction.Réponse originale ci-dessous
Oui, mais sans utiliser l'
open()
appel standard de Python . Vous devrez utiliser à laos.open()
place, ce qui vous permet de spécifier des indicateurs pour le code C sous-jacent.En particulier, vous souhaitez utiliser
O_CREAT | O_EXCL
. Depuis la page de manuel deopen(2)
underO_EXCL
sur mon système Unix:Ce n'est donc pas parfait, mais AFAIK est le plus proche pour éviter cette condition de course.
Edit: les autres règles d'utilisation
os.open()
au lieu deopen()
s'appliquent toujours. En particulier, si vous souhaitez utiliser le descripteur de fichier renvoyé pour la lecture ou l'écriture, vous aurez également besoin de l'un des indicateursO_RDONLY
,O_WRONLY
ouO_RDWR
.Tous les
O_*
indicateurs sont dans leos
module de Python , vous devrez doncimport os
et utiliseros.O_CREAT
etc.Exemple:
la source
Pour référence, Python 3.3 implémente un nouveau
'x'
mode dans laopen()
fonction pour couvrir ce cas d'utilisation (créer uniquement, échouer si le fichier existe). Notez que le'x'
mode est spécifié seul. L'utilisation des'wx'
résultats dans aValueError
as the'w'
est redondante (la seule chose que vous pouvez faire si l'appel réussit est de toute façon d'écrire dans le fichier; cela ne peut pas avoir existé si l'appel réussit):Pour Python 3.2 et inférieur (y compris Python 2.x), veuillez vous référer à la réponse acceptée .
la source
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
Ce code créera facilement un FICHIER s'il n'en existe pas.
la source
if
instruction, ce code efface le fichier.