Pregunta

Una aplicación quiere analizar y "ejecutar" un archivo, y quiere hacer valer el archivo es ejecutable por razones de seguridad.

momentos un pensamiento y se dan cuenta de este código inicial tiene una condición de carrera que hace que el sistema de seguridad ineficaz:

import os

class ExecutionError (Exception):
    pass

def execute_file(filepath):
    """Execute serialized command inside @filepath

    The file must be executable (comparable to a shell script)
    >>> execute_file(__file__)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ExecutionError: ... (not executable)
    """
    if not os.path.exists(filepath):
        raise IOError('"%s" does not exist' % (filepath, ))
    if not os.access(filepath, os.X_OK):
        raise ExecutionError('No permission to run "%s" (not executable)' %
                filepath)

    data = open(filepath).read()

    print '"Dummy execute"'
    print data

Existe la condición de carrera entre

os.access(filepath, os.X_OK)

y

data = open(filepath).read()

Dado que existe una posibilidad de que el archivo se sobrescribe con un archivo no ejecutable de diferentes contenidos entre estas dos llamadas al sistema.

La primera solución que tengo es para cambiar el orden de las llamadas críticos (y omitir la comprobación de existencia ahora redundante):

fobj = open(filepath, "rb")
if not os.access(filepath, os.X_OK):
    raise ExecutionError('No permission to run "%s" (not executable)' %
            filepath)

data = fobj.read()

¿Esto soluciona la condición de carrera? ¿Cómo puedo resolverlo correctamente?

fundamento régimen de la Seguridad, brevemente (pensé)

El archivo será capaz de ejecutar comandos arbitrarios en el interior de su medio ambiente, por lo que es comparable a una secuencia de comandos shell.

Había un agujero de seguridad en los escritorios libres con archivos .desktop que definen aplicaciones: El archivo puede especificar cualquier ejecutable con argumentos, y puede elegir su propio icono y el nombre. Por lo que un archivo descargado al azar podía ocultar detrás de cualquier nombre o icono y hacer cualquier cosa. Eso era malo.

Esto se resolvió al exigir que los archivos .desktop tienen el bit de ejecución conjunto, de lo contrario no se representa con nombre / icono, y el escritorio libre le preguntará al usuario si quiere iniciar el programa antes de comenzar.

Compare esto con muy buen diseño de Mac OS X: "Este programa ha sido descargado de la web, ¿está seguro de que desea abrirlo?".

Así que en la alegoría con esto, y el hecho de que usted tiene que chmod +x cáscara scripts que descargar, pensé en el diseño en la pregunta anterior.

palabras

cierre

Tal vez en conclusión, tal vez deberíamos mantenerlo simple: si el archivo debe ser ejecutable, hacen que sea ejecutable y permitir al kernel ejecutarlo cuando es invocado por el usuario. Delegación de la tarea que le corresponde.

¿Fue útil?

Solución

La ejecutabilidad se adjunta al archivo se abre, no hay nada que varios archivos de señalar al inodo contiene los datos que desea leer. En otras palabras, los mismos datos se pueden leer desde un archivo no ejecutable en el mismo sistema de ficheros en otro lugar. Además, incluso después de abrir el archivo, no se puede evitar que la ejecutabilidad de ese mismo archivo de cambiar, incluso podría ser no enlazados.

El "mejor esfuerzo" a su disposición como veo que sería hacer comprobaciones utilizando os.fstat en el archivo abierto, y compruebe el modo de protección y hora de modificación antes y después, pero en el mejor de esto sólo reducirá la posibilidad de que los cambios no se detectan mientras lee el archivo.

Pensándolo bien, si usted es el creador original de los datos de este archivo, usted podría considerar escribir un inodo que nunca ha vinculado con el sistema de archivos, en primer lugar, esta es una técnica común en el intercambio de archivos a través de la memoria. Alternativamente, si los datos contenidos deben eventualmente hecha pública a otros usuarios, se puede usar el bloqueo de archivos, y luego extender progresivamente los bits de protección a aquellos usuarios que así lo requieran.

En última instancia, debe asegurarse de usuarios maliciosos simplemente no tienen acceso de escritura en el archivo.

Otros consejos

No se puede resolver por completo esta condición de carrera - por ejemplo, en la versión donde se abre por primera vez, a continuación, comprobar los permisos, es posible que los permisos se cambian justo después de que haya abierto el archivo y simplemente antes de que haya cambiado los permisos.

Si usted puede mover atómicamente el archivo en un directorio en el que los malos potenciales no pueden alcanzar, entonces usted puede estar seguro de que nada sobre el archivo se cambió de debajo de la nariz, mientras que usted está tratando con él. Si los malos potenciales pueden llegar a todas partes , o no se puede mover el archivo a donde no pueden llegar, no hay defensa.

Por cierto, no es claro cómo este esquema, incluso si se podría hacer para trabajar, en realidad añadir ningún tipo de seguridad - seguramente si los malos puede poner envenenado contenido en el archivo no es más allá de ellos a chmod +x como así?

Lo mejor que puede hacer es:

  • guardar el permiso.
  • cambiarlo a su propio usuario único (algo con el nombre del programa) y prohibir a otros a ejecutarlo.
  • hacer que te cheques (con el permiso salvado si es necesario).
  • ejecutar el proceso.
  • retroceder el permiso a los salvados.

Por supuesto, hay inconvenientes, pero si su caso de uso es tan simple como que parecen decir, que podría hacer el truco.

Debe cambiar la propiedad de archivos de tal manera que un atacante no pueda acceder a él "chown root: nombre_archivo raíz". Hacer un "chmod 700 nombre_archivo" de manera que no hay otras cuentas pueden leer / escribir / ejecutar el archivo. Esto evita el problema de un TOCTOU todos juntos y así es como la gente a prevenir archivos de ser modificado por un atacante que tiene una cuenta de usuario en el sistema.

Otra manera de hacerlo es cambiar el nombre del archivo a algo inesperado, o incluso copiar el archivo completo - si no es demasiado grande - a un directorio temporal (cifrada si es necesario), te hacen cheques, a continuación, cambiar el nombre / copiar el Fichero anterior.

Por supuesto que es un proceso muy pesado.

Pero usted termina con que debido a que el sistema no se ha establecido la seguridad desde el principio. Un programa seguro sería firmar o cifrar los datos que quiere guardar la caja fuerte. En su caso, no es posible.

A menos que realmente el cifrado pesada, no existe manera de garantizar la seguridad 100 en una máquina que no controlas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top