13.07.2015 Views

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

5.5.PROGRAMACIÓN SEGURA 85No obstante, este problema no resulta tan grave como otro también relacionado con los coredump: cuando un programa setuidado vuelca su imagen el fichero resultante tiene el mismoUID que el UID real del proceso. Esto puede permitir a un usuario obtener un fichero conpermiso de escritura para todo el mundo pero que pertenezca a otro usuario (por ejemplo,el root): evidentemente esto es muy perjudicial, por lo que parece claro que en un programasetuidado necesitamos capturar todas las señales que Unix nos permita (recordemos quesigkill no puede capturarse ni ignorarse, por norma general).• Hay que asegurarse de que las verificaciones realmente verifican.Otra norma básica a la hora de escribir aplicaciones setuidadas es la desconfianza de cualquierelemento externo al programa; hemos de verificar siempre que las entradas (teclado, ficheros.. . ) son correctas, ya no en su formato sino más bien en su origen: ¿de quién proviene unarchivo del que nuestro programa lee sus datos, de una fuente fiable o de un atacante que porcualquier método – no nos importa cuál – ha conseguido reemplazar ese archivo por otro queél ha creado?• Cuidado con las recuperaciones y detecciones de errores.Ante cualquier situación inesperada – y por lo general, poco habitual, incluso forzada por unatacante – un programa setuidado debe detenerse sin más; nada de intentar recuperarse delerror: detenerse sin más. Esto, que quizás rompe muchos de los esquemas clásicos sobre programaciónrobusta, tiene una explicación sencilla: cuando un programa detecta una situacióninesperada, a menudo el programador asume condiciones sobre el error (o sobre su causa) queno tienen por qué cumplirse, lo que suele desembocar en un problema más grave que la propiasituación inesperada. Para cada posible problema que un programa encuentre (entradas muylargas, caracteres erróneos o de control, formatos de datos erróneos. . . ) es necesario que elprogramador se plantee qué es lo que su código debe hacer, y ante la mínima duda detener elprograma.• Cuidado con las operaciones de entrada/salida.La entrada/salida entre el proceso y el resto del sistema constituye otro de los problemascomunes en programas setuidados, especialmente a la hora de trabajar con ficheros; las condicionesde carrera aquí son algo demasiado frecuente: el ejemplo clásico se produce cuandoun programa setuidado ha de escribir en un archivo propiedad del usuario que ejecuta el programa(no de su propietario). En esta situación lo habitual es que el proceso cree el fichero,realize sobre él un chown() al rUID y al rGID del proceso (es decir, a los identificadores dequién está ejecutando el programa), y posteriormente escriba en el archivo; el esqueleto delcódigo sería el siguiente:fd=open("fichero",O_CREAT);fchown(fd,getuid(),getgid());write(fd,buff,strlen(buff));Pero, ¿qué sucede si el programa se interrumpe tras realizar el open() pero antes de invocara fchown(), y además el umask del usuario es 0? El proceso habrá dejado un archivo quepertenece al propietario del programa (generalmente el root) y que tiene permiso de escriturapara todo el mundo. La forma más efectiva de solucionar el problema consiste en que elproceso engendre un hijo mediante fork(), hijo que asignará a sus eUID y eGID los valoresde su rUID y rGID (los identificadores del usuario que lo ha ejecutado, no de su propietario).El padre podrá enviar datos a su hijo mediante pipe(), datos que el hijo escribirá en elfichero correspondiente: así el fichero en ningún momento tendrá por qué pertenecer al usuariopropietario del programa, con lo que evitamos la condición de carrera expuesta anteriormente.Sin embargo, un correcto estilo de programación no siempre es la solución a los problemas deseguridad del código; existen llamadas a sistema o funciones de librería que son un clásico a la horade hablar de bugs en nuestro software. Como norma, tras cualquier llamada se ha de comprobarsu valor de retorno y manejar los posibles errores que tenga asociados ([Sho00]), con la evidente

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!