Saltar al contenido

Escribir archivo con permisos específicos en Python

Solución:

¿Cuál es el problema? file.close() cerrará el archivo aunque esté abierto con os.open().

with os.fdopen(os.open('/path/to/file', os.O_WRONLY | os.O_CREAT, 0o600), 'w') as handle:
  handle.write(...)

Esta respuesta aborda múltiples preocupaciones con la respuesta de vartec, especialmente el umask preocupación.

import os
import stat

# Define file params
fname="/tmp/myfile"
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL  # Refer to "man 2 open".
mode = stat.S_IRUSR | stat.S_IWUSR  # This is 0o600.
umask = 0o777 ^ mode  # Prevents always downgrading umask to 0.

# For security, remove file with potentially elevated mode
try:
    os.remove(fname)
except OSError:
    pass

# Open file descriptor
umask_original = os.umask(umask)
try:
    fdesc = os.open(fname, flags, mode)
finally:
    os.umask(umask_original)

# Open file handle and write to file
with os.fdopen(fdesc, 'w') as fout:
    fout.write('somethingn')

Si el modo deseado es 0600, se puede especificar más claramente como el número octal 0o600. Aún mejor, solo usa el stat módulo.

Aunque primero se elimine el archivo antiguo, aún es posible una condición de carrera. Incluso os.O_EXCL con os.O_CREAT en las banderas evitará que se cree el archivo si existe debido a una condición de carrera. Esta es una medida de seguridad secundaria necesaria para evitar abrir un archivo que ya puede existir con una mode. En Python 3, FileExistsError con [Errno 17] se genera si el archivo existe.

Si no se configura primero el umask para 0 o para 0o777 ^ mode puede dar lugar a una incorrecta mode (permiso) establecido por os.open. Esto se debe a que el umask por lo general no es 0, y se aplicará a la especificada mode. Por ejemplo, si mi original umask es 2 es decir 0o002, y mi modo especificado es 0o222, si no configuro primero el umask, el archivo resultante puede tener un mode de 0o220, que no es lo que quería. Por man 2 open, el modo del archivo creado es mode & ~umask.

los umask se restaura a su valor original lo antes posible. Esta obtención y configuración no es segura para subprocesos, y una threading.Lock debe utilizarse en una aplicación multiproceso.

Para obtener más información sobre umask, consulte este hilo.

actualizar
Amigos, si bien les agradezco por los votos a favor aquí, yo mismo tengo que argumentar en contra de mi solución propuesta originalmente a continuación. La razón es hacer las cosas de esta manera, habrá una cantidad de tiempo, por pequeña que sea, en la que el archivo exista y no tenga los permisos adecuados en su lugar; esto deja abiertas amplias formas de ataque e incluso un comportamiento con errores.
Por supuesto, crear el archivo con los permisos correctos en primer lugar es el camino a seguir, en contra de la corrección de eso, utilizando Python with es solo un caramelo.

Así que, por favor, tome esta respuesta como un ejemplo de “qué no hacer”;

publicación original

Puedes usar os.chmod en lugar de:

>>> import os
>>> name = "eek.txt"
>>> with open(name, "wt") as myfile:
...   os.chmod(name, 0o600)
...   myfile.write("eeek")
...
>>> os.system("ls -lh " + name)
-rw------- 1 gwidion gwidion 4 2011-04-11 13:47 eek.txt
0
>>>

(Tenga en cuenta que la forma de usar octals en Python es siendo explícito, prefijándolo con “0o” como en “0o600“. En Python 2.x funcionaría escribiendo solo 0600 – pero eso es engañoso y desaprobado.)

Sin embargo, si su seguridad es crítica, probablemente debería recurrir a crearla con os.open, como lo haces y usas os.fdopen para recuperar un objeto de archivo Python del descriptor de archivo devuelto por os.open.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *