Debe introducir al menos 3 caracteres en el buscador.
Inicio / Wikis / Tutoriales / ¿Cómo Escribir Programas Seguros? - Manejo de ficheros

¿Cómo Escribir Programas Seguros? - Manejo de ficheros

 ----- 
Creative Commons Tutorial de Mononeurona.org - 08 de Noviembre de 2005
Temas Relacionados: Lenguaje C
6. Manejo de ficheros
La gestión de ficheros es siempre una tarea delicada, ya que se presta a ataques locales de "race condition". Se produce una "race condicion" cuando varios procesos están compitiendo por un recurso, y entre dos operaciones de uno de ellos se le cuela otro que cambia las características del recurso. Supongamos, por ejemplo, el caso siguiente:

if(access("/path/del/fichero",W_OK)
0) open(...);
El código anterior verifica que el usuario que ejecuta el programa tenga acceso de escritura al fichero en cuestión. Si es el caso, el open lo abre para escritura y graba en él.

Existe, sin embargo, una "race condition". Supongamos que un usuario malicioso crea un fichero válido, ejecuta el código anterior y, entre el "access()" y el "open()", borra el fichero y crea un enlace, pongamos, a "/etc/passwd". Las consecuencias pueden ser catastróficas. Evidentemente hace falta mucha casualidad para que las manipulaciones del usuario tengan lugar en el momento oportuno, pero no hay nada que le impida crear un proceso que lo intente repetidamente hasta tener éxito. A un ordenador no le cuesta nada intentarlo durante una semana seguida.

Es por ello que "access()" es una función anticuada que no debería ser utilizada nunca, y menos en procesos SUID. En su lugar deben utilizarse funciones como "stat()","lstat()" y "fstat()", como se verá dentro de un momento. Lamentablemente estas funciones carecen de la propiedad de "access()" que permite validar el acceso en función del usuario real del proceso, no del usuario efectivo. Ello la hace muy conveniente en procesos SUID.

La forma correcta de manejar un fichero es la siguiente:

  • Apertura de un fichero ya existente, como lectura o como "append":
lstat()
Vemos si es aceptable (enlace simbólico, dispositivo, fichero regular, etc).
open()
fstat()
Comparar el "lstat()" con el "fstat()". Si son diferentes es que alguien ha tocado el fichero mientras tanto.
  • Creación de un fichero nuevo:
open(O_CREAT|O_EXCL)
  • Truncado de un fichero:
lstat()
Vemos si es aceptable (enlace simbólico, dispositivo, fichero regular, etc).
open()
fstat()
Comparar el "lstat()" con el "fstat()". Si son diferentes es que alguien ha tocado el fichero mientras tanto.
ftruncate()
  • Borrado de un fichero:
La forma más sencilla consiste en
setegid(GID real)
seteuid(UID real)
unlink()
seteuid(UID privilegiado)
setegid(GID privilegiado)

En cualquier caso es preciso verificar que el usuario real (no el efectivo) del proceso tenga permiso para efectuar esa operación. Se puede hacer un "setegid()", "seteuid()" al usuario real antes de la operación y volver a usuario SUID de nuevo, de la misma forma, una vez validado el acceso. Otra posibilidad es crear una "pipe", hacer un "fork()" y que sea el hijo, previos "setgid()" y "setuid()", quien acceda al fichero. Ello es especialmente importante si en el "path" hay directorios, ya que de otra forma se nos obligaría a verificar componente a componente. Ese es precisamente el reciente problema de seguridad de los servidores web bajo Windows NT y el "::$DATA".

En los sistemas no POSIX que no tienen la opción de "saved uid/gid" se puede utilizar la llamada

setreuid(geteuid(),getuid());

para intercambiar el usuario real y efectivo.

Como regla general, nunca crees o leas ficheros en directorios en los que pueda escribir todo el mundo. Y cuando crees ficheros, hazlo con los privilegios más restringidos que sea posible. Debemos recordar también que la verificación del acceso se realiza en el "open()", no en los "read()" y "write()". Ello permite, por ejemplo, abrir un fichero mientras somos privilegiados, despojarnos de los privilegios y seguir escribiendo en él.
Autor y licencia de '¿Cómo Escribir Programas Seguros? - Manejo de ficheros'
Mononeurona.org Extraído de: http://www.mononeurona.org/index.php?idp=535

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.

Wikis relacionados con '¿Cómo Escribir Programas Seguros? - Manejo de ficheros'

Se discuten SSH, SSL, TSL y HTTPS, los protocolos utilizados en la actualidad para intercambiar... Más »
Se discuten SSH, SSL, TSL y HTTPS, los protocolos utilizados en la actualidad para intercambiar... Más »
Este documento recopila la información de importantes autores en cuanto a programas de investigación se... Más »
El poder de Unix1 se esconde en pequeños comandos que no parecen ser muy útiles... Más »
Un sistema informático utiliza ordenadores para almacenar datos, procesarlos y ponerlos a disposición de quien... Más »
¿Estás seguro de que deseas eliminar este capítulo?