|
|

CGI (Common Gateway Interface), ejecución de binarios.
CGI no es un lenguaje. Los cgi-bin son programas que se ejecutan en el servidor, pueden servir para tratar información, como pasarela con una aplicación o base de datos o para generar documentos html de forma automática.
La interfaz de pasarela común (Common Gateway Interface, CGI) es un protocolo genérico que permite extender las capacidades de HTTP. Los programas en CGI añaden funcionalidad al servidor Web, funcionalidad que podría abrir agujeros de seguridad en el servidor, ya que una aplicación en CGI mal diseñada podría permitir acceso total o parcial al servidor.
Es una especificación para permitir a un servidor de WWW ejecutar un programa externo y devolver los resultados al navegador. Mediante esta interfaz es posible correr cualquier programa que se encuentre accesible al servidor, de modo que no hay límite para las tareas que se pueden realizar. El programa de CGI obtiene información del usuario a través de una "forma", que es un conjunto de botones, espacios de texto y menús que se despliegan en la pantalla de un navegador.
En general, es necesaria la presencia de dos elementos, una página Web en formato HTML con un formulario donde el usuario introduce sus datos, y un programa CGI en el servidor, que recibe y procesa los datos del usuario. Cuando la forma se encuentra llena, el usuario lo envía utilizando un botón. El servidor recibe los datos, los pasa al programa externo y éste devuelve los resultados de la operación, para que el servidor los regrese a su vez al usuario.
Las aplicaciones del CGI son numerosas: herramientas de búsqueda, formas de registro, libros de visitas, contadores de accesos, sistemas de bases de datos, grupos de discusión, personalización de páginas, tiendas y catálogos electrónicos, y más. La gran mayoría de las aplicaciones que existen en la WWW actualmente, dependen exclusivamente del CGI.
Como se vio con anterioridad, una de las principales utilidades de los cgi-bin es tratar los resultados de un formulario (FORM). Estos programas pueden ser escritos en cualquier tipo de lenguaje de programación y son ejecutados en el servidor cuando se realiza su referencia. Algo importante es que el programa debe ser ejecutable en el servidor, por tanto al ser el servidor una maquina UNIX, no se puede utilizar por ejemplo los compiladores de los PC, sino los del servidor. Los lenguajes más comunes para escribir estos programas son el lenguaje perl, C ó bien un script escrito en cualquier shell (csh, sh, ksh ó zsh).
Un script CGI puede ser escrito en cualquier lenguaje que pueda leer de STDIN, escribir en STDOUT, y leer variables de entorno como virtualmente cualquier lenguaje de programación. Algo importante es que los cgi-bin deben tener una extensión especial .cgi, o bien, encontrarse en un directorio especial llamado cgi-bin. Cuando se referencie en una pagina html un binario, cualquier fichero con la extensión cgi, en el servidor se ejecutará este programa y la salida se enviará al cliente de la WWW.
Objetivos al escribir CGIs
Los objetivos que nos guiarán a la hora de escribir CGI's seguros se resumen en los siguientes:
Mecanismo de entrega y procesamiento de datos de un CGI
En la figura está representada de manera simplificada el proceso que tiene lugar desde que al usuario se le presenta el formulario de entrada de datos hasta que obtiene la página de resultado de procesar esos datos:
El navegador Web recibe el archivo HTML y lo
visualiza en pantalla. Es común que la página contenga
alguna información relacionada con el resultado del
procesamiento de los datos, junto con algún enlace para
regresar a la página del formulario, en el paso 1. Es importante resaltar que no es imprescindible la presencia de un formulario para invocar desde el navegador al CGI del servidor. Muchas veces, basta con pinchar en un enlace para llamar al CGI y también es posible llamarle directamente desde la ventana de URL, introduciendo el URL completo del programa CGI.
Qué lenguaje utilizar
A menudo se plantea la discusión de qué lenguaje resulta el más adecuado a la hora de escribir CGI's seguros. En una primera aproximación, puede considerarse a los lenguajes compilados como más seguros por las siguientes razones:
No obstante, no hay que olvidar que los lenguajes interpretados son más sencillos de entender y rápidos de probar (ya que no necesitan pasar por todo el proceso de compilación y enlazado), y además su manejo de cadenas es mucho más sofisticado, lo que los hace menos propensos a errores con búferes de texto.
Llamada a programas
Uno de los aspectos más potentes de la programación en CGI es la capacidad de las aplicaciones de invocar utilidades del sistema u otros programas, con la posibilidad de capturar su salida. Sin embargo, desgraciadamente, esta libertad puede convertirse en un arma de doble filo, ya que resulta igualmente sencillo subvertir los argumentos de esos comandos, de manera que se produzcan acciones inesperadas e indeseables.
Dependiendo del lenguaje de programación empleado, existen varias formas de invocar comandos:
En la medida de lo posible se debe evitar abrir un subshell, pero en el caso de que fuera estrictamente necesario, ya que las acciones requeridas no se pueden realizar usando las capacidades del lenguaje de programación, entonces se debe evitar pasar como argumentos al proceso la entrada del usuario. Desgraciadamente, esto también es inevitable, por lo que se deberá filtrar la entrada que suministra, en busca de metacaracteres como `$|;>*<& ['\]"( ~?)\n\r.
No obstante, suele resultar más conveniente especificar una lista de caracteres permitidos que de caracteres peligrosos, ya que si te olvidas de especificar un carácter, no ocurre nada desastroso; mientras que si te olvidas de especificar un carácter peligroso, como los retornos de carro, se puede comprometer la seguridad de todo el sistema.
Los cgi-bin se podrán escribir con las instrucciones normales del lenguaje de programación pero hay ciertos aspectos a tener en cuenta:
Variables de entorno
Para pasar datos el servidor al cgi-bin utiliza una serie de variables de entorno, que quedan definidas al ejecutar el script. Las variables de entorno más interesantes son:
PATH_INFO = /camino/fichero
La información que se incluye será pasada de forma codificada al cgi-bin, de forma que los espacios se convierten en signos '+' y los caracteres especiales se codifican de la forma %xx, donde xx el código ASCII en hexadecimal del caracter. Esto debe ser tenido en cuenta cuando se interprete la información obtenida en formato URL.
?variable1=valor1&variable2=valor2& ... &variablen=valorn
REMOTE_HOSTEl ordenador desde el que se ejecuto el cgi-bin.
REMOTE_ADDRDirección IP del ordenador remoto que ejecuto el cgi-bin.
CONTENT_LENGTHEl número de caracteres enviados por el cliente al cgi-bin.
HTTP_USER_AGENTEl cliente de la WWW que ejecuta el cgi-bin,
el formato general es:
El cgi-bin podría enviar un distinto código HTML según cada cliente.
Entrada de datos al cgi-bin
Para los formularios que utilizan el método POST, la información es enviada al cgi-bin por la entrada estándar (stdin). El servidor envía las variables de entorno CONTENT_LENGTH y CONTENT_TYPE indicando la longitud y el tipo de datos enviados. El servidor no esta obligado a enviar una marca de final de fichero tras los datos enviados, por tanto la variable CONTENT_LENGTH debe ser tenida en cuenta para determinar la cantidad de datos enviados. CONTENT_TYPE suele contener el valor application/x-www-form-urlencoded, que indica que se trata de información con codificación URL.
En esta codificación como se vio antes los espacios se convierten en signos '+' y los caracteres especiales se codifican de la forma %xx, donde xx el código ASCII en hexadecimal del carácter. Por tanto esto debe ser tenido en cuenta cuando se interpreten los datos enviados del formulario. Las variables del formulario se enviarán de la forma:
variable1=valor1&variable2=valor2& ... &variablen=valorn
Salida de datos del cgi-bin
El cgi-bin debe enviar sus datos a la salida estándar (stdout), esta salida puede ser un documento generado por el cgi-bin o instrucciones al servidor para obtener el documento correcto.
La salida del cgi-bin debe comenzar con una pequeña cabecera que identificará al documento. Las directivas que definen esta cabecera serán:
Por ejemplo:
printf ( "Content-type: text/html\n\n" );
Sería el comienzo de la salida de cgi-bin escrito en C que comienza a generar código html.
Tras la cabecera se incluirán dos caracteres de retorno de carro (\n), siendo obligatorio para que sea bien interpretada la cabecera de cgi-bin, si no se respeta esto la salida del cgi-bin podría indicarnos el error "Server Error 500". Después de definida la cabecera se podrá generar la salida del cgi-bin, que se interpretará según el valor dado a Content-type.
Dónde poner los CGI
Existen dos prácticas generalizadas. La primera de ellas, y más recomendable, consiste en designar un único directorio donde se almacenarán todas las aplicaciones en CGI, típicamente el directorio cgi-bin, con privilegios limitados, de manera que los usuarios locales no puedan instalar, eliminar ni editar programas. Por el contrario, la segunda permite la ejecución de cualquier fichero con la extensión, p.e., .cgi como un programa CGI, lo cual lo considero desaconsejable. La primera práctica presenta las siguientes ventajas:
Para que sea posible ejecutar el binario (cgi-bin), será necesario que el fichero tenga los permisos de forma correcta, Tu programa CGI debe ser ejecutable para ese nombre de usuario, además de poder ser leído si es un script Perl o un shell script. En Unix, fija los permisos correctos con "chmod 750 *.cgi" (o "chmod 755 *.cgi", si tu servidor no tiene accesos de grupo a tus archivos-- intenta ambos, o pregunta a tu webmaster).
Ejemplotendrá que ejecutar en Unix el siguiente comando:
www2> chmod 755 programa.cgi
Con esto el programa será ejecutable por el servidor.
Si tu script no corre:
Cómo configurar el servidor, Cómo correr el servidor
Cuando se ejecuta un CGI, corre con el UID del propio servidor Web, lo cual significa que un CGI con errores permitiría a un atacante correr otros programas con el UID del servidor. En estas circunstancias, resulta evidente que el servidor Web nunca deberá correr como root. Aunque el servicio de Web, típicamente en el puerto 80, debe ser iniciado por el root, el fichero http.conf no debería contener la línea "User root". Si lo hiciera, entonces cualquier guión que se ejecutase en el servidor Web lo haría como el superusuario, con los riesgos que eso conllevaría.
Una solución común es correr el servidor como el usuario genérico nobody, que carece de privilegios. Si bien representa una mejora respecto a root, el inconveniente que presenta es que otros procesos corren asimismo como nobody, por lo que todos gozarían de los mismos privilegios. En su lugar, es más conveniente correr el servidor como un usuario real, por ejemplo www, perteneciendo al grupo www.
Enviando un Archivo Existente como Respuesta
Si tu respuesta HTML siempre es la misma, o si quieres responder con uno de los archivos existentes, puedes encontrar útil el encabezado de respuesta "Location:". Úsalo para redireccionar el navegador a otro URL.
Como ejemplo, si tu script CGI escribe la siguiente línea a STDOUT:
Location: response.html
seguida de una línea en blanco, entonces el navegador remoto obtendrá a response.html y lo tratará como respuesta de tu script CGI. Puedes redireccionar al navegador a un URL ya sea relativo o absoluto.
En esta situación, no imprimas el encabezado de respuesta "Content-type:".
La mayoría de los scripts CGI regresan datos HTML, pero puedes regresar cualquier tipo de datos que tú quieras. Solamente usa el tipo MIME correcto en la línea "Content-type:", seguida por la línea en blanco requerida, seguida por los datos de los recursos que estás enviando de regreso. En el caso de los archivos HTML, esos datos es el texto HTML.
En el caso de imágenes, audio o video son datos binarios. Por ejemplo, para responder con un archivo gif, usa:
Content-type: image/gif
GIF89a&%*$@#--- contenido binario del archivo GIF aquí ---$(*&%(*@#......
Tu archivo HTML puede cargar una imágen generada por script con
<img src="gifmaker.cgi?param1=value1¶m2=value2">
Uno de mis ejemplos favoritos es was el Render Interactivo de Gráficas, que renderea íconos 3-D de acuerdo con los colores, forma, textura, iluminación, etc. que definas. Puedes usar el ícono de resultado en tus páginas Web como balas de lista o reglas horizontales mejoradas.. Nota: Este sitio ha perdido temporalmente su lugar; el autor dice que éste será eventualmente el punto de la nueva localización.
Tipos MIME
Los tipos MIME son cadenas de caracteres estándar de caso sensitivo que identifican el tipo de datos usado a través de Internet para muchos propósitos. Comienzan con el tipo general de datos (como text, image, o audio), seguido por un slash, y terminando con el tipo específico de datos (como html, gif, or jpeg). Los archivos HTML se identifican con text/html, y los GIFs y JPEGs se identifican con image/gif y image/jpeg.
Ganando Más Control con Scripts de Encabezado No-Analizados
Normalmente, cuando tu script CGI imprime los encabezados "Content-type:", "Location:", u otros, el servidor analiza estos encabezados y genera la respuesta HTTP apropiada para el usuario. Ocasionalmente puedes querer un control más fino sobre la respuesta HTTP. La mayoría de los servidores Web soportan scripts de encabezados no-analizados (o "NPH"), que generan una respuesta HTTP completa y omite el análisis normal del servidor.
Para usarlos, necesitas saber un poco de HTTP-- específicamente, los formatos de líneas de estado y líneas de encabezado.
En tu script de encabezado no-analizado, solamente imprime el HTTP completo de las líneas de estado y encabezado donde un script normal imprimiría la línea "Content-Type:". Incluye la línea en blanco de trailer. Cualquier cosa que imprima tu script se envía al usuario verbatim, como la respuesta HTTP completa, sin modificaciones del servidor.
Nombra tus scripts NPH comenzando con algo con "nph-", como "nph-miscript.cgi"; cada script cuyo nombre comienza con "nph-" será manejado como un script NPH. Esto funciona en la mayoría de los servidores, inlcuyendo Apache y NCSA. Otros servidores pueden usar esquemas diferentes para identificar scripts NPH; lee los documentos o pregunta a tu webmaster.
Como un ejemplo de un script NPH, ve CGIProxy.
Desventajas
La mayor desventaja es que es necesario conectarse al servidor cada vez que se quiera ejecutar un programa y además debe crearse una página nueva para mostrar los resultados. Esto afecta seriamente el tiempo de respuesta y hace muy difícil la programación de algunas aplicaciones, como charlas en tiempo real y juegos. Además, para utilizar el CGI se requiere acceso directo al servidor y conocimiento de las especificaciones de la interfaz y de algún lenguaje de programación como C, Perl o Visual Basic.
Dónde está el riesgo
Cuando los usuarios envían un formulario o invocan un CGI de alguna otra forma, en definitiva se les está permitiendo ejecutar remotamente un programa en el servidor. Es más, puesto que la mayoría de CGI's aceptan datos de la entrada de usuario (bien después de rellenar un formulario o directamente desde la línea de URL), en esencia se les brinda a los usuarios la oportunidad de controlar cómo se ejecutará el CGI, de manera que podrían intentar la introducción de una serie de parámetros inesperados hábilmente manipulados para que el CGI funcionase maliciosamente.
Vulnerabilidad de los CGIs
El punto vulnerable de la programación en CGI, es decir, la amenaza que representan para la seguridad del servidor, es doble:
Nunca fiarse del usuario
Uno de los medios de ataque más utilizados por los hackers consiste en enviar parámetros a un programa, de manera que no pueda procesarlos y entre en un estado inestable o bien ejecute acciones indeseadas.
El ejemplo más explotado en el mundo de los CGI es la manipulación de formularios: los formularios normalmente presentan una serie de campos dentro de los cuales se puede escribir texto, así como listas desplegables, botones de selección, etc. Un error muy común entre los programadores novatos consiste en asumir que la entrada del programa CGI provendrá de los datos rellenados por el usuario a partir del formulario.
Sin embargo, resulta muy sencillo cargar en el disco local la página HTML con el formulario y manipularla a voluntad (por ejemplo variando los campos ocultos), o bien directamente introducir los datos manipulados en la ventana del URL, modificando los argumentos esperados por el CGI. Por lo tanto, debe tenerse en cuenta lo siguiente:
Caminos y nombres de ficheros
Caminos
No se debe confiar en los caminos contenidos en la variable PATH a la hora de ejecutar ciertas acciones, ya que esa variable podría contener cualquier cosa, truco comúnmente usado por atacantes para que la variable apunte al programa que desean que sea ejecutado por el CGI en lugar del esperado. Por este motivo es mejor utilizar caminos completos.
En su defecto, si se necesitan caminos relativos, se puede especificar el valor de la variable PATH al principio del CGI.
Por idénticas razones, es conveniente no añadir "." en el camino.
Nombres de ficheros
Presumiblemente, los nombres de ficheros que aparecen codificados en el programa CGI son seguros, siempre que no se usen caminos relativos (los servidores NT no permiten caminos relativos). Por esta razón no se debe confiar en las variables PATH o PATH_INFO. También se puede considerar el prohibir caracteres como "..", para evitar que se puedan producir ataques que obliguen a abrir archivos confidenciales (v. ejemplo). Asimismo, suele constituir una buena práctica el asegurarse de que los archivos creados son los que se pretendía crear.
Si el programa CGI maneja datos confidenciales, suele convenir no utilizar el directorio /tmp, ya que podría quedar en él información valiosa.
Llamada a programas
Uno de los aspectos más delicados de la programación con CGI, es la llamada a otros programas o comandos del sistema desde la aplicación CGI. Un ejemplo típico sería el enviar un correo a un usuario a la dirección que éste ha introducido a través de un formulario. Para ello puede invocarse al programa sendmail, abriendo un shell mediante diversos mecanismos. Ya veremos cómo estas llamadas pueden ser subvertidas por un atacante, de manera que se ejecuten otros comandos además del esperado, con el fin de causar daños al sistema u obtener información sobre el mismo.
Cómo enviar los datos
GET y POST son dos métodos empleados para enviar los datos de los formularios desde el navegador al servidor Web, especificados mediante la directiva METHOD. La principal diferencia entre POST y GET es que el CGI recibirá los datos enviados con POST leyendo la entrada estándar, mientras que los enviados con GET se recibirán por líneas de comandos y la variable de entorno QUERY_STRING. Desde un punto de vista puramente práctico, debido a que muchos sistemas operativos ponen límite a la longitud de la línea de comandos, suele ser mejor usar POST, reservando GET para formularios con pocos datos.
Desde el punto de vista de la seguridad la verdad es que da igual uno u otro, si bien las peticiones enviadas mediante GET quedan registradas en los ficheros de registro, con todos sus argumentos, por lo que si se enviase información confidencial sin cifrar, estos datos quedarían en el fichero log, donde a lo mejor alguien no autorizado podría husmear posteriormente. O lo que es peor, agujeros como el que descubrió Brumleve en Netscape, exponen el cache, con toda la información que almacena, como todos los URLs que han sido solicitados, por supuesto con los datos con que se rellenaron los formularios, como podría suceder con el número de la tarjeta de crédito.
Tabla comparativa entre GET y POST
Acción |
GET |
POST |
| ¿Añade los datos con que se rellena el formulario al URL solicitado? | S |
N |
| ¿Limitado en la cantidad de datos que se pasan al URL solicitado? | S |
N |
| ¿Usado típicamente fuera de formularios HTML? | S |
N |
| ¿Utiliza la variable de entorno QUERY_STRING del servidor? | S |
N |
| ¿Envía los datos al URL solicitado en una transacción separada con el servidor? | N |
S |
| ¿Utiliza las variables del servidor CONTENT TYPE y CONTENT LENGTH? | N |
S |
| ¿Puede escribir datos en el servidor? | N |
S |
¿Cómo decir si un CGI es seguro?
1. ¿Es muy complejo?
2. ¿Lee o escribe ficheros en el servidor?
3. ¿Interactúa con otros programas del sistema?
4. ¿Corre con privilegios suid?
5. ¿Se valida la entrada procedente de formularios?
6. ¿Se emplean nombres de camino explícitos?
Preguntas tomadas de la FAQ sobre seguridad en WWW.
A evitar
No fiarse de los campos ocultos
Los campos ocultos se denominan así porque no se visualizan en la pantalla del navegador, pero sí se ven si se lista el código fuente en HTML de la página. Por lo tanto, cualquiera puede cargar la página en su disco local y editarla, modificando los valores de los campos ocultos. En consecuencia, nunca se deben utilizar para contener información confidencial ni confiar en ellos para almacenar información sensible (como precio de un producto). El servidor deberá contrastar la información recibida procedente de los campos ocultos.
No fiarse del lugar de ejecución
Como ya se ha dicho, los CGI's no tienen por qué ejecutarse necesariamente desde el formulario donde aparecen. Pueden mandarse ejecutar directamente desde la ventana de URL, por lo que podrían faltar parámetros o estar manipulados.
Script de correo CGI
Uno de los usos más comunes de un script CGI es enviar por correo datos a una dirección de email. Así que aquí está un simple script que hace precisamente eso, escrito en Perl, llamado mailer.pl.
Haz estos cambios al script antes de ponerlo en su lugar:
Para añadir un formulario en su página usted deberá escribir el siguiente código en su página:
<HTML>
<BODY>
<CENTER><H1> Mi primer formulario</H1></CENTER>
<FORM METHOD="POST" ACTION="http://cgi.futurnet.es/cgi-bin/FormMail.pl">
<H3>Introduzca su nombre</H3>
<INPUT TYPE="text" NAME="Nombre" size="30">
<H3>Introduzca su dirección de Correo Electrónico</H3>
<INPUT TYPE="text" NAME="e-mail" size="30">
<H3>Indique su Hobby</H3>
<INPUT TYPE="radio" NAME="Hobbys" VALUE=" Deporte"> Deporte
<INPUT TYPE="radio" NAME="Hobbys" VALUE=" Música"> Música
<INPUT TYPE="radio" NAME="Hobbys" VALUE=" Cine">Cine
<<h3>su Edad </H3>
<SELECT NAME="Edad" SIZE="Auto">
<OPTION>---su Edad---</OPTION>
<OPTION>Menos de 15</OPTION>
<OPTION>Menos de 25</OPTION>
<OPTION>Menos de 35</OPTION>
<OPTION>Menos de 50</OPTION>
<OPTION>Más de 50</OPTION>
</SELECT><BR>
<i> La dirección a la que van los datos
debe rellenarse en el siguiente campo</i><BR>
<INPUT TYPE="Hidden" NAME="recipient" VALUE="su_dirección@futurnet.es">
<i>Al ser del tipo Hydden (oculto) el usuario que
rellena el formulario no la ve, por lo que no la
puede modificar, si se quiere dar opción al usuario de
cambiarla, debe especificarse como tipo Text</i>
<H3>Y por último los botones </H3><BR>
<INPUT TYPE="Submit" VALUE="Enviar!">
<INPUT TYPE="Reset" VALUE="Borrar">
</FORM>
</BODY>
</HTML>
Contadores
Añadir un contador resulta extremadamente sencillo. Tan sólo deberá insertar el contador como si de una imagen se tratase (realmente lo es) con la salvedad de añadir una serie de parámetros:
emboss
fatpt
katt011
katt078
odb
pdw
fuego
thunder 
![]()
Por lo tanto si usted quiere utilizar el tipo de letra Katt011, y si su nombre de usuario es juan, la línea que deberá introducir en su página sería:
<IMG SRC="http://195.76.98.24/scripts/counter/counter.exe?-sKatt011+juan">
Hiperenlaces (links) en menu desplegable
Para añadir un link en menú desplegable en su página usted deberá escribir el siguiente código:
<HTML><BODY>
<CENTER><H1> Mi primer Link en un Menu desplegable<H/1></CENTER>
<FORM METHOD=POST ACTION="http://cgi.futurnet.es/cgi-bin/jumper.pl" >
<SELECT NAME="url" >
<OPTION SELECTED VALUE="http://www.futurnet.es">Futurnet
<OPTION SELECTED VALUE="http://www.ole.es">OLE
<OPTION SELECTED VALUE="http://www.yahoo.com">Yahoo
<OPTION SELECTED VALUE="http://www.lycos.com">Lycos
</SELECT>
<INPUT TYPE="Submit" VALUE="Saltar!">
</FORM> </BODY></HTML>
Enviando Datos de Formas por Correo sin CGI
Existe una forma bastante pobre de enviar por correo datos de una forma que solamente usa HTML: en la etiqueta <form>, fija el atributo action a "mailto:" URL, y el atributo enctype a "text/plain". La mayoría de los navegadores manejan esto correctamente, por ejemplo, enviar datos en un mensaje de correo. Por ejemplo,
<form action="mailto:me@myhost.com" enctype="text/plain">
Existen desventajas: no puedes controlar el formato del texto enviado, y no puedes enviar una respuesta de regreso al usuario. Asímismo no todos los navegadores soportan este estilo de etiqueta <form>.
Como crear un CGI en Jet y ponerlo en tu página
Voy a describir aquí los pasos que uso yo para compilar, copiar y ejecutar un CGI en C y en PERL. Se supone que eres cliente de Jet Internet. Si no lo eres, puede que los pasos a seguir sean diferentes pero no deberían variar mucho. Si tienes algún problema, consulta con tu proveedor.
Si usas C...
Compilando tu CGI
Para compilar el fichero en el servidor, hay que pedir amablemente a los de jet que nos den una cuenta personal en users.jet.es para compilar CGIs. Una vez obtenido el permiso, podemos seguir con el ejemplo. Tenemos el fichero 'prueba.c' en el directorio c:\pruebas.
Contenido del fichero 'prueba.c':
#include<stdio.h>
main()
{
printf("Content-type: text/html\n\n");
printf("¡Esto funciona!");
}
Este fichero imprime crea una página web en la que pone:
¡Esto funciona!
Fijaros que en un CGI lo primero que hay que poner es la cabecera, en este caso : Content-type: text/html\n\n
El '\n' es un retorno de linea. Siempre debe de haber 2.
Ahora nos conectamos con un programa de FTP (recomiendo el FTP Cute) al directorio que se nos ha asignado en users.jet.es
Copiamos el fichero 'prueba.c' en formato ASCII al directorio de users.jet.es que se nos haya asignado.
Una vez copiado y sin cerrar el FTP, abrimos el Telnet. El Telnet lo puedes encontrar en tu disco duro en C:\WINDOWS si usas Windows 95. Una vez ejecutado, nos conectamos a users.jet.es
Después de pasar por la petición de clave, ponemos 'dir' y pulsamos return.
Si lo hemos hecho todo bien, deberíamos de ver nuestro fichero 'prueba.c' en el directorio.
Ahora tecleamos 'gcc -o prueba.cgi prueba.c -s' para compilar el fichero.
'gcc' invoca al compilador de ficheros C
'-o prueba.cgi' le dice el nombre del fichero a crear. Si nos olvidamos de este parámetro, obtendremos un fichero llamado 'a.out'. Si este es el caso, podemos teclear 'mv a.out prueba.cgi' para cambiarle el nombre. 'prueba.c' es el nombre del fichero que vamos a compilar. '-s' indica al compilador que reduzca todo lo posible el fichero de salida.
Después de la compilación y si tecleamos dir, deberíamos ver 2 ficheros: 'prueba.c' y 'prueba.cgi'. Salimos del Telnet.
Copiando el CGI a tu página
Debemos de copiar el fichero 'prueba.cgi' al directorio de nuestra página web. Si todavía tenemos abierta la sesión FTP sólo hay que pulsar el botón actualizar sesión.
Ahora copiamos el fichero 'prueba.cgi' a nuestro disco duro. Podemos cerrar después la sesión FTP.
Abrimos otra sesión FTP, esta vez hacia el directorio de nuestra página web y copiamos el fichero 'prueba.cgi' allí.
Ya tenemos el CGI en nuestra página web. Si ahora vamos a un navegador y tecleamos la dirección donde se encuentra el CGI lo ejecutaremos. Ejemplo:
http://www.jet.es/gregorio/prueba.cgi
Sin embargo recibiremos un molesto error. Tranquilos, no pasa nada. Ahora lo solucionamos.
Darle permiso de ejecución al CGI para ejecutarlo
Los sistemas UNIX tiene activada una opción por defecto que anula la posibilidad de ejecución de cualquier cosa a no ser que le dado a nuestro fichero un permiso especial. Por eso antes recibíamos el molesto mensaje de error.
Para darle permiso, se puede usar el programa de FTP. En el caso del FTP Cute, una vez vemos el fichero al que queremos darle el permiso de ejecución, clickeamos en el con el botón derecho del ratón y seleccionamos 'File Attributes' del menú emergente.
Ahora hay que darle permiso de lectura o lectura/escritura a nuestro CGI 'prueba.cgi'
Deberíamos recibir un mensaje advirtiéndonos que hemos cambiado los atributos de un fichero.
Ahora si ejecutamos el CGI desde nuestro navegador, deberíamos ver el esperado mensaje "¡Esto funciona!".
Si usas PERL...
Creando tu CGI
Como el Perl no es un lenguaje compilado como el C, nos saltaremos la ardua tarea de compilar nuestro fuente. Simplemente, crearemos un fichero de texto llamado prueba.txt. DEBERIAMOS usar el procesador de textos más simple que tengamos a fin de que no nos salve carácteres extra en el fichero como hacen el Wordperfect o el Works. Se supone que vamos a usar el Notepad de Windows 95 (también sirve el EDIT del MS-DOS siempre que no usemos carácteres españoles como los acentos o la eñe).
Contenido del fichero prueba.txt:
#!/usr/bin/perl
print "content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Aprendiendo a crear CGIs</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "Enhorabuena. Acabo de crear un CGI ¡y funciona!\n";
print "</BODY></HTML>\n";
Fijaros que en un CGI lo primero que hay que poner es la cabecera, en este caso : Content-type: text/html\n\n
El '\n' es un retorno de linea. Siempre debe de haber 2.
Copiando el CGI a tu página
Debemos de copiar el fichero 'prueba.txt' al directorio de nuestra página web. Abrimos una sesión FTP hacia el directorio de nuestra página web y copiamos el fichero 'prueba.txt' allí.
Ya tenemos el CGI en nuestra página web. Si ahora vamos a un navegador y tecleamos la dirección donde se encuentra el CGI lo ejecutaremos. Ejemplo:
http://web.jet.es/gregorio/prueba.txt
Sin embargo, veremos el fuente del fichero como si fuese un texto normal. Tranquilos, no pasa nada. Ahora lo solucionamos.
Solucionando los problemas
La respuesta es sencilla: el navegador no sabe que eso es un CGI. Pues no tenemos más que cambiar la extensión de txt por cgi. La razón de no haberlo hecho antes, es que nuestro programa de FTP DEBE transferir los archivos con formato ASCII, es decir, simples ficheros de texto, si intentamos copiar directamente el fichero con el nombre prueba.cgi, casi seguro que no nos va a funcionar porque lo intenará transferir en formato BINARIO.
En los sistemas UNIX, ningún programa funciona hasta que le demos permiso de ejecución. Para darle permiso, se puede usar el programa de FTP. En el caso del FTP Cute, una vez vemos el fichero al que queremos darle el permiso de ejecución, pinchamos en el con el botón derecho del ratón y seleccionamos 'File Attributes' del menú emergente.
Ahora hay que darle permiso de lectura o lectura/escritura a nuestro CGI 'prueba.cgi'
Deberíamos recibir un mensaje advirtiéndonos que hemos cambiado los atributos del fichero.
Si ejecutamos ahora el CGI desde nuestro navegador, deberíamos ver el esperado mensaje de enhorabuena.
Cómo probar un CGI en casa
Un CGI que cojas de cualquier sitio no te va a funcionar a la primera. Las diferencias entre las configuraciones de los servidores hacen algunas veces imposibles de "portar" un programa de un servidor a otro.
Sobre todo la diferencia entre servidores Windows y Unix, algunas veces es tremenda. De hecho si coges un CGI en Perl y te funciona en un servidor Unix, lo tienes que cambiar casi por completo para que te funcione con, digamos, el WebSite. La mayor cosa que hay que tener en cuenta, es que el salto de línea del Perl para Unix es diferente al del para Windows.
Yo lo he probado, y después de más de cinco horas (a lo mejor soy un poco torpe) he conseguido poner un contador que me funciona en Jet a la perfección. Es decir, a no ser que te montes tu servidor Unix en casa no hay forma humana para probar los CGI. Justamente por esta razón se hacen CGIs en Perl, ya que no se tiene que compilar el (o los) ficheros cada vez que se haga una modificación (normalmente porque no funciona el CGI). Por esta misma razón (la de no tener que compilar) es bueno el Perl.
Por cierto: el PERL esta disponible para (casi) todas las plataformas, y esta hecho para el manejo de "cadenas".
Usando el Website
¿Cómo puedo probar CGIs escritos en Perl en un servidor WEB como el Website...?
Aquí va un ejemplo para el WebSite.
Crea el fichero hello.pl en el directorio website\cgi-shl que contenga el siguiente texto:
---
require "cgi-lib.pl";
print &PrintHeader;
print '<html>Hello World!</html>';
---
El archivo cgi-lib.pl esta en el directorio website
Crea el fichero hello.htm en el directorio website\htdocs
---
<html>
<body>
<FORM METHOD="POST" ACTION="/cgi-bin/hello.pl">
<input type="submit" value="dime Hello world!"> </p>
</form>
</body>
</html>
---
Una vez que hayas creado los ficheros y tengas el Website activado, teclea esta dirección en tu navegador:
http://localhost/hello.htm
NTPerlb
El NTPerlb es un intérprete Perl para Win32. Un script en Perl se puede probar en Windows95 o NT. El único problema es pasarle los parámetros: con GET es fácil en NT 4 pero en Windows 95 no se pueden meter '=' en las variables de entorno. Con POST hay que poner el CONTENT_LENGTH.
El NTPerlb se puede encontrar en cualquier parte. Puedes buscar en http://ftpsearch.ntnu.no/ftpsearch .
El NTPerlb se puede ejecutar sin tener un servidor web, con lo que se puede probar un CGI en Perl casi del todo antes de ponerlo en una página.
Formularios caseros
¿Hay alguna forma de mandar un formulario sin usar CGIs?
Sí, pero el formulario sólo funcionará si usas Netscape 3.0 o Internet Explorer 4.0 y versiones posteriores. Como ya sabrás, en la etiqueta FORM tienes que decirle un método a usar. Imagínate lo siguiente usando un CGI:
<FORM action = "/cgi-bin/form.cgi" method=post>
Luego tendrías que pasarle al CGI un parámetro con la dirección a la que mandas el email. Para hacerlo de forma casera, cámbialo por esto:
<FORM action = "mailto:gregorio@jet.es" method = post >
¿Qué
son?
Las directivas de Server-Side Includes (SSI) constituyen poderosas herramientas para aumentar la productividad del programador, ya que permiten al servidor modificar automáticamente el documento solicitado antes de ser enviado al navegador del cliente. Su propósito principal es insertar dentro de las páginas Web el contenido de ficheros de texto, información dinámica sobre ficheros (como por ejemplo su tamaño) o la salida resultante de la ejecución de ciertos comandos del sistema ya preseleccionados o libres.
Los Server-Side Includes pueden contener a su vez otros Server-Side Includes, de forma que se puede llegar a introducir una cantidad enorme de texto en una página con la inclusión de un único comando.
Los Server-Side Includes insertan el texto en el fichero exactamente en el mismo sitio donde aparecen. En otras palabras, se reemplazan a sí mismos en el instante en que se sirven las páginas que los contienen.
Peligros
En la práctica, los Server-Side Includes permiten toda clase de trucos cuando se combinan con CGIs que modifican páginas Web, como en el escenario del libro de visitas: los visitantes a una página disponen de un "libro" en el que pueden dejar un texto, que en principio podría incluir etiquetas en HTML y también, si la entrada no se filtra, includes como los siguientes:
<!--#exec cmd="rm rf /;cat /etc/passwd" -->
<!--#include file="archivo_secreto" -->
Soluciones
Existen varias soluciones para paliar estas amenazas.
A continuación cito los recursos que he utilizado como fuentes para esta sección sobre CGI y otros que me han parecido interesantes.
Capítulo de la FAQ sobre seguridad en WWW de Lincoln Stein, dedicado a CGI. Excelente.
Capítulo 9 del libro CGI Developer's Guide por Eugene Eric Kim.
Extensa compilación de textos sobre seguridad en CGI, con ejemplos en C y Perl.
Completo curso sobre seguridad en CGI.
Security Issues When Installing and Customizing Pre-Built Web Scripts
Recomendaciones a tener en cuenta cuando se instalan guiones CGI en nuestro servidor.
Algunas ideas sobre seguridad en el servidor y también en CGI.
Algunos breves consejos a la hora de escribir guiones CGI.
Colección de punteros a recursos sobre seguridad en CGI.
Más punteros a recursos sobre el tema.
The CGI Resource Index: Documentation: Security
bravenet.com