Al considerar qué tan seguro es algo, debe asumir que el atacante puede iniciar sesión como su usuario de www-data y tener un shell. Esto no significa que su atacante realmente pueda obtener un shell, pero puede haber muchas maneras en que el atacante puede ejecutar comandos de shell arbitrarios; podrían ser resultados de errores de la biblioteca como shellshock, u omisiones en su código.
La forma más segura
La mejor manera de hacerlo es, como dijo @AlexeyVesnin, usar un proceso especializado para hacer el trabajo. Haga que este proceso escuche en un socket (dominio de Unix, por lo que no es accesible desde la red), lea su entrada desde dicho socket, desinfecte la entrada (!), Haga el trabajo y devuelva algún resultado al socket, desde donde El script del servidor web lee los resultados. Cualquier autorización (el usuario debe ingresar alguna contraseña en el sitio web para que se le permita hacer esto) debe manejarse en ese proceso, y el usuario de www-data no debe poder leer ninguno de esos datos de autorización.
El modo sudo en su mayoría seguro
En caso de que su presupuesto, o su habilidad, no haga viable este mejor enfoque, usar el enfoque sudo no es completamente incorrecto, pero debe restringir los permisos de sudo al mínimo que realmente necesita. Por ejemplo, supongamos que desea mostrar los datos actuales de E / S del disco en su sitio web, para los que necesita llamar a iotop
:
-
haga un script, en este ejemplo /var/www/bin/get-disk-io
, que extraiga los datos que necesita:
/usr/sbin/iotop -b -n 1 | /usr/bin/head -2
- No permita que la persona que llama al script pase ningún parámetro, es decir, el script no debe acceder a
$1
, $2
, ..., $*
, $@
- En caso de que tenga que usar parámetros, desinfectelos primero en su script. Preste especial atención al espacio en blanco o cualquier carácter inusual que pueda estar oculto en los parámetros.
- Asegúrese de indicar la ruta completa de acceso a cada comando en esa secuencia de comandos, para que los atacantes no puedan reemplazar ninguno de esos comandos por su cuenta
- Permitir el acceso a este script, y solo este script , en
/etc/sudoers
- Asegúrese de que
env_reset
esté en la política de valores predeterminados en su archivo sudoers
Tenga en cuenta que esto es aún más seguro que un programa suid, ya que (a) puede restringir quién puede ejecutarlo, por lo que un atacante que obtenga la capacidad de ejecutar un programa con un usuario diferente no podrá usarlo. (b) no puede pasarle parámetros arbitrarios, (c) el entorno está saneado por sudo
y (d) puede hacer sudo log cuando se ejecuta el comando, por lo que tiene un seguimiento de auditoría que un programa suid no te da.
La forma suid
Nota: no hagas esto a menos que sepas lo que estás haciendo. Si está preguntando, o leyendo, esta pregunta en stackexchange, probablemente no lo haga. Así que no hagas esto.
Si establece el propietario de un ejecutable para un determinado usuario ( chown user /my/executable/file
), luego establece el bit suid ( chmod u+s /my/executable/file
), entonces ese programa se ejecutará bajo los permisos de ese usuario cada vez que se ejecute. Entonces, por ejemplo, chown root /bin/cat; chmod u+s /bin/cat
ejecutará cada invocación de cat
con derechos de raíz, lo que significa que puede leer cada archivo en el sistema independientemente de sus derechos de acceso. No intentes esto en un sistema que esté conectado a una red, ni siquiera durante 5 minutos para "verificar si funciona" .
- En muchos sistemas Unix, esto funciona solo para programas compilados, no para scripts que necesitan un intérprete.
- En algunas configuraciones, por ejemplo, si ejecuta el programa en
strace
, el bit s
no tiene ningún efecto
- En las configuraciones de NFS, la raíz a menudo no tiene acceso a los archivos en el servidor NFS, por lo que esto podría reducir lo que puedes hacer.
El modo de Linux restringido-suid
Linux tiene un sistema de capacidades, que funciona casi como suid, pero una granularidad mucho más fina. Por ejemplo, si necesita un proceso para poder usar los números de puerto por debajo de 1024, en los sistemas unix clásicos, debe ejecutar el comando como root, lo que significa que necesita hacer el anterior chown/chmod u+s
stuff, que le permite usar esos puertos Números, pero también otorga acceso al sistema de archivos. Linux le permite dar la capacidad de puerto sin todo lo que viene con la raíz:
setcap cap_net_bind_service+EP /path/to/my/program
Haz man 7 capabilities
para aprender más. Si considera seriamente dar suid a un programa, piense dos veces si establecer una capacidad no es una mejor idea.