1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
<?xml version="1.0" encoding="iso-8859-1"?>
<chapter id="security">
<title>Seguridad</title>
<simpara>
PHP es un potente lenguaje y el interprete, tanto incluido en
el servidor web como modulo o ejecutado como un binario <acronym>
CGI</acronym>, puede acceder a ficheros, ejecutar comandos y abrir
comunicaciones de red en el servidor. Todas estas caracteristicas
hacen que lo que se ejecute en el servidor web sea inseguro por
defecto.
PHP ha sido disenado especificamente, para ser un lenguaje mas seguro
para escribir programas CGI, que Perl o C y con la correcta seleccion
de las opciones de configuración del tiempo de compilación y ejecucion
se consigue la exacta combinación de libertad y seguridad que se necesita.
</simpara>
<simpara>
Ya que existen diferentes modos de utilizar PHP, existen multitud
de opciones de configuración que permiten controlar su funcionamiento.
Una gran selección de opciones garantiza que se pueda usar PHP para
diferentes usos, pero tambien significa que existen combinaciones de
estas opciones y configuraciones del servidor que producen instalaciones
inseguras. Este capitulo explica las diferentes combinaciones de opciones
de configuración y las situaciones donde pueden ser usadas de manera segura.
</simpara>
<sect1 id="security.cgi-bin">
<title>Binarios CGI</title>
<sect2 id="security.cgi-bin.attacks">
<title>Posibles ataques</title>
<simpara>
Usando PHP como un binario <acronym>CGI</acronym> es una opción para
instalaciones que por cualquier causa no quieren integrar PHP como
modulo en el software servidor (p.ej: Apache), o usaran PHP con
diferentes clases de CGI wrappers para crear entornos chroot y setuid
seguros para los scripts. Esta configuración implica generalmente
el instalar el binario ejecutable de PHP en el directorio cgi-bin
del servidor web. El documento del CERT <ulink url="&url.cert;">
CA-96.11</ulink> recomienda no instalar interpretes en cgi-bin.
Aunque el binario PHP puede ser usado como interprete independiente,
PHP esta diseñado para prevenir los ataques que esta configuración
hace posible.
</simpara>
<itemizedlist>
<listitem>
<simpara>
Accediendo a ficheros del sistema: <filename
role="url">http://my.host/cgi-bin/php?/etc/passwd</filename>
</simpara>
<simpara>
La información introducida despues del signo de interrogación (?)
es transferida como argumento de la línea de comando al intérprete
por el interfaz del CGI. Normalmente los interpretes abren y ejecutan
el fichero especificado como el primer argumento en la línea de comando.
</simpara>
<simpara>
Cuando se ejecuta como un CGI script, PHP rechaza interpretar los
argumentos de la línea de comando.
</simpara>
</listitem>
<listitem>
<simpara>
Accediendo cualquier documento web en el servidor: <filename
role="url">http://my.host/cgi-bin/php/secret/doc.html</filename>
</simpara>
<simpara>
La información con el camino (path) de la URL despues del
nombre del binario PHP, <filename role="uri">/secret/doc.html</filename>
es usada convencionalmente para especificar el nombre del fichero
que sera abierto e interpretado por el programa <acronym>CGI</acronym>.
Normalmente, algunas directivas del servidor web (Apache:Action) son
usadas para redireccionar peticiones de documentos como <filename
role="url">http://my.host/secret/script.php3</filename> al
interprete PHP. Con esta configuración, el servidor web comprueba
primero los permisos de acceso al directorio <filename
role="uri">/secret</filename>, y despues crea la petición
redireccionada <filename
role="url">http://my.host/cgi-bin/php/secret/script.php3</filename>.
Desafortunadamente, si la petición es hecha de esta forma en un
principio, el servidor web no comprueba los permisos de acceso del
fichero <filename role="uri">/secret/script.php3</filename>, sino
solamente del fichero <filename role="uri">/cgi-bin/php</filename>.
De esta manera cualquier usuario que pueda acceder <filename
role="uri">/cgi-bin/php</filename> tambien puede acceder a
cualquier documento protegido en el servidor web.
</simpara>
<simpara>
En PHP, a la hora de compilar, la opción de configuracion <link
linkend="enable-force-cgi-redirect">--enable-force-cgi-redirect</link>
y las directivas de configuracion a la hora de ejecutar <link
linkend="ini.doc-root">doc_root</link> y <link
linkend="ini.user-dir">user_dir</link> pueden ser usadas para prevenir
este ataque, si el arbol de documentos del servidor tiene cualquier
directorio con acceso restringido. Ver mas adelante la explicacion de las
diferentes combinaciones.
</simpara>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="security.cgi-bin.default">
<title>Caso 1: solamente se sirven ficheros publicos</title>
<simpara>
Si tu servidor no contiene informacion que este protegida
con clave o acceso de control de IPs, no se necesitan estas
opciones de configuracion. Si tu servidor web no permite realizar
redireccionamientos, o el servidor no tiene modo de comunicar
al binario PHP que la peticion es una peticion segura redireccionada,
podeis especificar la opcion <link
linkend="enable-force-cgi-redirect">--disable-force-cgi-redirect</link>
en el script de configuracion. De todas maneras, teneis que aseguraros
que vuestros scripts PHP no confíen en la manera al llamar
al script, ni de forma directa <filename
role="php">http://my.host/cgi-bin/php/dir/script.php3</filename> o
por redireccion <filename
role="php">http://my.host/dir/script.php3</filename>.
</simpara>
<simpara>
Redireccionamiento puede ser configurado en Apache usando las
directivas AddHandler y Action (ver mas abajo).
</simpara>
</sect2>
<sect2 id="security.cgi-bin.force-redirect">
<title>Caso 2: usando --enable-force-cgi-redirect</title>
<simpara>
Esta opcion a la hora de compilar previene que alguien llame
PHP directamente con una url como la siguiente <filename
role="php">http://my.host/cgi-bin/php/secretdir/script.php3</filename>.
PHP solamente analizara en este modo si ha pasado por una regla
de redireccionamiento en el servidor.
</simpara>
<simpara>
Normalmente la redireccion en la configuracion de Apache es hecha
con la siguientes directivas:
</simpara>
<programlisting role="apache-conf">
Action php3-script /cgi-bin/php
AddHandler php3-script .php3
</programlisting>
<simpara>
Esta opcion ha sido solo comprobada con el servidor web Apache, y
depende de Apache para fijar la variable de entorno CGI no estandar
<envar>REDIRECT_STATUS</envar> en las peticiones de redireccionamiento.
Si tu servidor web no soporta ningun modo para informar si una peticion
es directa o redireccionada, no podeis usar esta opcion y debereis usar
alguno de los otros modos de ejecucion de la version CGI documentados aqui.
</simpara>
</sect2>
<sect2 id="security.cgi-bin.doc-root">
<title>Caso 3: Usando doc_root or user_dir</title>
<simpara>
Incluir contenidos activos, como script y ejecutables, en
el directorio de documentos del servidor web, es algunas veces
considerada una practica insegura. Si por algun fallo de configuracion,
los scripts no son ejecutados pero mostrados como documentos HTML,
cualquiera podra conseguir codigo registrado o informacion de
seguridad, como p.ej: claves de acceso. Por ello, muchos administradores
prefieren utilizar otra estructura de directorios que contenga solamente
los scripts, los cuales seran solamente accesibles via PHP CGI, y por
ello siempre seran interpretados y no mostrados.
</simpara>
<simpara>
Habra que tener en cuenta que si el metodo que asegura que las peticiones no son
redireccionadas, como hemos descrito en la seccion anterior, no
esta disponible, sera necesario configurar un script doc_root
que sea diferente del "web document root".
</simpara>
<simpara>
Podeis definir el script PHP "document root" con la directiva
de configuracion <link linkend="ini.doc-root">doc_root</link> en el
<link linkend="configuration.file">fichero de configuracion</link>,
o definir la variable de entorno <envar>PHP_DOCUMENT_ROOT</envar>.
Si esta definida, la version CGI de PHP siempre obtendra el nombre
del fichero a abrir con <parameter>doc_root</parameter> y el
camino (path) utilizado en la peticion, asi podeis estar seguros
que ningun script sera ejecutado fuera de este directorio
(excepto para <parameter>user_dir</parameter>, ver a continuacion)
</simpara>
<simpara>
Otra opcion que se puede usar aqui es <link
linkend="ini.user-dir">user_dir</link>. Cuando user_dir no esta
definido, lo unico que controla la apertura del fichero es
<parameter>doc_root</parameter>. Si intentamos abrir una url
tal como esta <filename role="url">http://my.host/~user/doc.php3</filename>
no se abrira un fichero en el directorio de usuarios, en su lugar
se abrira un fichero llamado <filename role="uri">~user/doc.php3</filename>
en el directorio doc_root. (si, un directorio que empieza por tilde
[<literal>~</literal>]).
</simpara>
<simpara>
Si user_dir esta definido por ejemplo como <filename
role="dir">public_php</filename>, una peticion tal como <filename
role="url">http://my.host/~user/doc.php3</filename>, abrira un
fichero llamado <filename>doc.php3</filename> en el directorio
llamado <filename role="dir">public_php</filename> del directorio
"home" del usuario. Si el directorio del usuario es <filename
role="dir">/home/user</filename>, el fichero ejecutado sera
<filename>/home/user/public_php/doc.php3</filename>.
</simpara>
<simpara>
La expansion de <parameter>user_dir</parameter> ocurre sin tener
en cuenta la configuracion de <parameter>doc_root</parameter>, de
este modo se puede controlar los accesos al directorio principal
(document root) y al directorio de usuario separadamente.
</simpara>
</sect2>
<sect2 id="security.cgi-bin.shell">
<title>Caso 4: Analizador PHP fuera del arbol web.</title>
<para>
Una opcion muy segura es poner el analizador binario PHP, en algun lugar
fuera del arbol de ficheros web. Por ejemplo en <filename
role="dir">/usr/local/bin</filename>. La unica pega real de esta opcion
es que habra que poner una linea similar a:
<informalexample>
<programlisting>
#!/usr/local/bin/php
</programlisting>
</informalexample>
como primera linea en cualquier fichero que contenga codigo PHP.
Tambien sera necesario asignar al fichero permisos de ejecucion.
De esta manera, es tratado de la misma manera que cualquier otro
CGI script escrito en Perl o sh o otro lenguaje utilizado para
scripts y que utilicen el mecanismo <literal>#!</literal> para
ejecutarse.
</para>
<para>
Para conseguir que PHP maneje correctamente con esta configuracion,
la informacion de <envar>PATH_INFO</envar> y <envar>PATH_TRANSLATED</envar>,
el analizador PHP deberia ser compilado con la opcion de configuracion
<link linkend="enable-discard-path">--enable-discard-path</link>.
</para>
</sect2>
</sect1>
<sect1 id="security.apache">
<title>Modulo Apache</title>
<simpara>
Cuando PHP es usado como modulo Apache, hereda los permisos de
usuario de Apache (normalmente "nobody")
</simpara>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
|