Tema 3: CGI: Common Gateway Interface (Interfaz Público de Pasarela) 1. 2. 3. 4. 5. 6. Introducción. Invocación del CGI. El paso de datos. Documento devuelto. Seguridad. Ejemplos. IST - 2006 CGI. 1 1. Introducción Generación dinámica de contenido ? La 2º generación web ? La 1º Generación web sólo disponía de documentos estáticos. ? La 2º Generación permite la generación dinámica de contenido. ? Nace en 1996 cuando NCSA crea el Common Gateway Interface (CGI). ? Rige como interaccionan los servidores HTTP con programas especiales que se ejecutan en la máquina servidora, destinados a procesar la información que envían los clientes Web y generar documentos de forma dinámica. ? A estos programas especiales se les llama aplicaciones o módulos CGI (la mayoría de veces, simplemente CGI ). ? Son la primera de una serie de soluciones ideadas para publicar información dinámica (extraída normalmente de una BD). ? El contenido es cambiante con el tiempo, dependiendo del entorno, del usuario, de los datos enviados, etc. IST - 2006 Tema 3: CGI. CGI. 2 1 1. Introducción Generación dinámica de contenido Servidor HTTP CGI (Common Gateway Interface ) Respuesta HTML QUERY STRING QUERY STRING BASE DE DATOS Respuesta HTML Cliente Servidor IST - 2006 CGI. 3 1. Introducción Funcionamiento básico (I) Maquina Servidora Variables de Entorno Línea de comando Servidor HTTP Cliente Petici ón HTTP Entrada estándar Interfaz CGI Aplicación CGI (Perl, C, C++, java, etc.) Interfaz CGI Respuesta HTTP Proceso httpd Salida estándar Proceso cgi Cabecera NPH o Simple + HTML IST - 2006 Tema 3: CGI. CGI. 4 2 1. Introducción Funcionamiento básico (II) ? El usuario: ? Rellena un formulario HTML y envía lo datos. ? La acción va asociada a la URL de una aplicación CGI. ? El servidor Web: ? Lanza la aplicación CGI como un proceso independiente ? Pasa los datos del formulario a través de: variables de entorno, línea de comandos y entrada estándar. ? La aplicación CGI: ? Recoge los datos, accede a la BD y, con el resultado, produce un documento HTML. ? Devuelve al servidor el documento precedido de una cabecera HTTP (nph o simple), a través de la salida estándar. ? El servidor Web: ? Devuelve el resultado, casi directamente, al navegador. IST - 2006 CGI. 5 1. Introducción Funcionamiento básico (III) <HTML> <HEAD><TITLE>Formulario Simple</TITLE></HEAD> <BODY> <H2>El formulario más simple</H2> <FORM name="login" action="http://www.tecnun.es/cgi-bin/ii/CGI0.exe" method ="POST" target="_self"> Introduzca su nombre:&nbsp;&nbsp; <INPUT type="text" name="nombre" size="25"><BR><BR> <INPUT type="submit" value="Enviar ">&nbsp;&nbsp;&nbsp; <INPUT type="reset" value="Borrar"> </FORM> </BODY> </HTML> Estructura General: ? ? ? ? Elementos de entrada de datos Botón de envío (Submit) Método de envío de datos Acción que el servidor debe emprender cuando reciba los datos IST - 2006 Tema 3: CGI. CGI. 6 3 1. Introducción Ejemplos de usos ? Aplicaciones web. ? Recoger y procesar la información de un formulario. ? Generar dinámicamente contenido a partir de esa información ? Generar dinámicamente información a partir de parámetros cambiantes con el tiempo. ? p.e. un periódico electrónico, información bursátil, etc. ? Generar dinámicamente contenido a partir de la consulta a una base de datos. ? p.e. los motores de búsqueda. ? Mapa de imágenes activo. ? Contar el número de accesos a la página. ? Anuncios incrustados (banners). ? Etc... IST - 2006 CGI. 7 1. Introducción Lenguaje de la aplicación CGI ? En principio, no hay restricción ? Compilados: ? C, C++, Pascal, Fortran, etc. ? Directamente ejecutables. ? El ejecutable suele estar en /cgi-bin ? Son más eficientes ? Interpretados: ? Shell-Script, Phyton, Tcl, Awk, etc., pero sobre todo Perl: ?El Perl es muy potente en el tratamiento de cadenas. ? La ejecución de la aplicación la realiza el interprete de ordenes (el interprete se pone previamente en funcionamiento). Cuando acaba la ejecución del cgi, también acaba la del interprete. ? El script suele estar también en /cgi-bin ? Son más fáciles de depurar, modificar y mantener IST - 2006 Tema 3: CGI. CGI. 8 4 2. Invocación del CGI Para que funcione como CGI ?El servidor Web distingue un módulo CGI de cualquier otro fichero convencional: ?Por su ubicación (Windows y Linux) ?Residen en directorios virtuales especiales del sistema. El nombre más habitual es /cgi-bin. ?Por su extensión (sobre todo en Windows) ?El nombre del fichero suele tener extensión .cgi ?Por sus permisos (sobre todo en Unix) ?El módulo CGI debe tener permisos de lectura y ejecución para todo el mundo IST - 2006 CGI. 9 2. Invocación del CGI Formas de invocar un CGI (I) ? Directamente desde el Navegador (método GET) ? Indicando su URL en el campo Dirección ? Como destino de un enlace (GET): <a href="/cgi-bin/prueba.cgi"> Enlace al CGI de pruebas </a> ? Al actuar sobre un mapa activo (mapa de imágenes en el lado del servidor) – (GET): <a href= "http://www.uv.es/cgi-bin/mapa_imagenes/campus_burj.cgi"> <img alt="Mapa del campus de burjasot" src="mapa_burj.gif" ismap> </a> IST - 2006 Tema 3: CGI. CGI. 10 5 2. Invocación del CGI Formas de invocar un CGI (II) ? Como dirección origen de una imagen (GET). ? La salida de la aplicación CGI debe ser de tipo imagen. ? Es una forma de incrustar banners. <img src="/cgi-bin/banner.cgi" alt="publicidad"> ? Como acción asociada a un formulario HTML (GET-POST) ? Es el uso más común de las aplicaciones CGI. ? El método de invocación (GET o POST) establece la manera en que el CGI recibirá los parámetros. <form action="/cgi-bin/test.cgi" method="POST"> IST - 2006 CGI. 11 2. Invocación del CGI Métodos de envío de los datos ? ? Los clientes web utilizan los métodos GET y POST del protocolo HTTP para enviar la información al servidor, aunque especificamente el método GET es usado para obtener información ( a trav és de URLs en navegador o a trav és de hiperlinks). Cualquiera de los dos puede usarse cuando se env ía un formulario HTML. El método GET: ? La información se incluye codificada en la propia URL (a continuación de ?), dentro de la cabecera HTTP. http:// www.uv.es /cgi-bin/ist /CGI0 .exe?nombre1=valor1 &nombre2=valor2 ? Ideal para enviar poca información (suele estar limitada a 200 caracteres como máximo). ? La petición puede ser guardada y enviada por e-mail ? No es muy seguro, ya que los datos viajan junto a la dirección y son vistos por todo el mundo en la barra de direcciones. ? Es el método utilizado por defecto. ? El método POST: ? La información se incluye en el cuerpo del mensaje HTTP. ? La cantidad de información enviada puede ser mucho mayor ( longitud ilimitada) ? El intercambio es invisible para el cliente ? La URL no cambia en absoluto ? Sólo suele utilizarse dentro de los formularios. ? La petición no puede ser guardada ni enviada por e-mail e incluso no puede ser refrescada. ? Ofrece un extra de seguridad puesto que el “access log” del servidor que guarda las URLs no guarda los datos enviados mediante POST. ? En ambos casos, el navegador codifica los datos (URLEncoded) antes de enviarlos. IST - 2006 CGI. 12 Tema 3: CGI. 6 2. Invocación del CGI Organización de los datos enviados ? Los mapa activos envían al CGI: ? Las coordenadas donde ha sido pinchado dicho mapa, separadas por comas. ? El método utilizado es GET. ? Los datos del formulario son enviados al CGI: ? Como un conjunto de pares nombre=valor, donde nombre será el atributo NAME de cada entrada INPUT, TEXTAREA o SELECT, incluida dentro del formulario. ? Los pares están separados por el carácter '& '. ? El método puede ser tanto GET como POST. IST - 2006 CGI. 13 2. Invocación del CGI Ejemplos de información enviada (I) ? Mapa activo: GET /cgi-bin/fotos/mapa.cgi?123,45 HTTP/1.1 Host: www.uv.es Accept: text/plain, text/html, image/*, */* User-Agent: Mozilla/4.0 (MSIE 5.01; Windows NT 5.0) ? Formulario con método GET GET /cgi-bin/visita?nombre=Luis+S%E1nchez &direccion=Valencia HTTP/1.1 Host: www.uv.es Accept: text/plain, text/html, image/*, */* User-Agent: Mozilla/4.0 (MSIE 5.01; Windows NT 5.0) IST - 2006 Tema 3: CGI. CGI. 14 7 2. Invocación del CGI Ejemplos de información enviada (II) ? Formulario con método POST: POST /cgi-bin/visita HTTP/1.1 Host: www.uv.es Accept: text/plain, text/html, image/*, */* Content-type: application/x-www-form-urlencoded Content-length: 33 User-Agent: Mozilla/4.0 (MSIE 5.01; Windows NT 5.0) nombre=Luis+S%E1nchez&direccion=Valencia IST - 2006 CGI. 15 3. Paso de datos desde el Servidor al CGI Datos enviados en la URL y en el cuerpo ? El servidor se encarga de hacer llegar la información recibida al CGI: ?Si el método de envío fue GET ?Los datos codificados son accesible por el CGI a través de la variable de entorno QUERY_STRING (texto de la url desde la 1ª ' ? ' hasta el final). ?Si no se ha utilizado ' = ', el servidor también hace llegar los datos decodificados, a la aplicación CGI, como argumentos (en C++: argc, argv). ?Si fue POST ?Llegarán codificados por la entrada estándar. ?En C++: cin.read ?La variable CONTENT_LENGTH indicará el número de bytes de la información. IST - 2006 Tema 3: CGI. CGI. 16 8 3. Paso de datos desde el Servidor al CGI Variables de entorno (I) ? Las variables de entorno son un conjunto de variables que el servidor Web debe poner en el entorno de ejecución de los CGI. ? Contienen: ? El resto de información enviada por el cliente (cabecera HTTP del mensaje de petición). ? También incluyen características particulares del entorno (relacionadas con la ejecución del servidor). ? La forma de acceder a estas variables depende del lenguaje y del S.O. ? En C++: getenv(VARIABLE) ? Las variables se escriben en mayúsculas. ? Un valor nulo equivale a su no definición. ? El número de variables depende del servidor. IST - 2006 CGI. 17 3. Paso de datos desde el Servidor al CGI Variables de entorno (II) ?Relacionadas con la identificación del cliente: ?REMOTE_ADDR ?Dirección IP del cliente web que invocó al CGI. En caso de que el cliente realice la conexión a través de un proxy, aparece la dirección del proxy. ?REMOTE_USER (Cabecera HTTP Authoritation) ?Nombre del usuario autenticado. ?AUTH_TYPE (Cabecera Authoritation) ?Tipo de autenticación empleada (Basic, Digest, nula). ?HTTP_FROM (Cabecera From) ?Dirección de correo del usuario. IST - 2006 Tema 3: CGI. CGI. 18 9 3. Paso de datos desde el Servidor al CGI Variables de entorno (III) ?Relacionadas con la identificación del servidor: ?SERVER_NAME ?Nombre del servidor (alias DNS o dirección IP), tal como se indicó en el URL. ?HTTP_HOST (Cabecera Host) ?Nombre del servidor, tal como se incluyó en la cabecera HTTP. ?SERVER_PORT ?El número de puerto por el cual fue recibida la petición. ?SERVER_SOFTWARE ?Nombre y versión del software que implementa el servidor (p.e: Apache/1.3.14). ?SERVER_PROTOCOL ?Versión del protocolo HTTP que utiliza el servidor. IST - 2006 CGI. 19 3. Paso de datos desde el Servidor al CGI Variables de entorno (IV) ?Relacionadas con la conexión: ?HTTP_ACCEPT (Cabecera Accept) ?Lista de tipos MIME aceptados por el cliente (separados por comas). ?HTTP_REFERER (Cabecera Referer) ?URL de la página desde la que se accedió al CGI. ?HTTP_USER_AGENT (Cabecera User-Agent) ?Identificación del navegador usado por el cliente. ?HTTP_COOKIE (Cabecera Cookie) ?Cookies retornadas por el cliente. ?HTTPS ?Con el valor a “on”, indica que la conexión es SSL. IST - 2006 Tema 3: CGI. CGI. 20 10 3. Paso de datos desde el Servidor al CGI Variables de entorno (V) ?Relacionadas con los parámetros de entrada: ?REQUEST_METHOD ?Método de invocación utilizado (GET, POST, ..). ?QUERY_STRING ?Parámetros pasados al CGI utilizando el método GET (en la URL, detrás del símbolo “?”) ?CONTENT_TYPE ?Tipo MIME de la información presente en la entrada estándar. ?Sólo se utiliza para los accesos POST. ?CONTENT_LENGTH ?Tamaño de la información presente en la entrada estándar (enviada usando el método POST), o NULL. IST - 2006 CGI. 21 3. Paso de datos desde el Servidor al CGI Variables de entorno (VI) ?Relacionadas con la localización del CGI: ?GATEWAY_INTERFACE ?Versión del protocolo CGI implementado (Normalmente es: CGI/1.1) ?SCRIPT_NAME ?URL local del programa CGI. ?DOCUMENT_ROOT ?Directorio raíz del servicio Web. ?PATH_INFO ?Camino extra expresado en el URL del CGI. ?PATH_TRANSLATED ?Concatenación de DOCUMENT_ROOT y PATH_INFO. IST - 2006 Tema 3: CGI. CGI. 22 11 4. Documento devuelto Resultado de la aplicación GCI ? El CGI devuelve al servidor su resultado a través de la salida estándar ? C++: cout ? El resultado consta normalmente de: ? Una cabecera HTTP ?Normalmente: Content-Type: text/html ? Una línea en blanco. ? Un documento MIME completo. ? El servidor completa la información de la cabecera, y el resultado final es enviado al cliente. ? Un CGI puede generar tres tipos de resultados: ? Un documento MIME completo, con su cabecera completa (nph) ? Un documento MIME completo, con una cabecera simple. ? La localización de un documento. IST - 2006 CGI. 23 4. Documento devuelto Documento con cabecera nph ?CGI con salida NPH. ?Non-Parsed Header ?Exige el prefijo nph- ?Devuelve un documento HTTP completo. ?El CGI toma control total de la conexión HTTP. ?El servidor no filtra la cabecera, y se limita a pasar tal cual el resultado al cliente. ?Debe incluir al menos la primera línea de la cabecera HTTP, indicando la versión del protocolo y el código de estado HTTP/1.0 200 OK Content-Type: ...... ......... IST - 2006 Tema 3: CGI. CGI. 24 12 4. Documento devuelto Documento con cabecera simple ? Salida normal de un CGI ? Devuelve un conjunto reducido de cabeceras HTTP. El resto de campos son rellenados por el servidor. ? Por lo general: ? 1ª línea de estado (opcional): Status: Código de estado. ? Si no se incluye se supone “200 OK” ? 2ª línea: “Content-Type: tipo MIME ” (obligatoria) ? Siguiente línea: en blanco ? Resto: documento completo del tipo indicado ? Ejemplo: Content-Type: text/html <html><head><title> Título del documento </title> </head><body> .... </body></html> IST - 2006 CGI. 25 4. Documento devuelto Localización de un documento ?Devolución de una dirección url ?1ª línea: Location: URL local o remota ?URL local: resuelta por el propio servidor Location: /mensaje/error.html ?URL remota: el cliente debe seguir la URL Location: http://www.w3.org/mensaje/index.html ?2ª línea: en blanco ?Si la url es completa, el servidor genera una respuesta: “302 Found”. El cliente recogerá el documento referenciado (location). ?Si la url es parcial, el servidor devuelve el documento. IST - 2006 Tema 3: CGI. CGI. 26 13 5. Seguridad Riesgos ?Cuando un usuario invoca un CGI, está ejecutando remotamente un programa en el servidor. ?El usuario podría pasar al CGI una serie de parámetros manipulados para controlar su ejecución. ?Amenazas: ?El usuario puede “engañar” al CGI, para que ejecute comandos imprevistos, provocando daños. ?Sobre todo, cuando dentro del CGI hay llamadas a otros programas o comandos del S.O. ?Existe la posibilidad de que la aplicaciones CGI revele de forma innecesaria información sobre el servidor que pueda comprometer su seguridad. IST - 2006 CGI. 27 5. Seguridad Recomendaciones (I) ?Al administrador Web: ?Todos los programas CGI deberían residir en un directorio especial del servidor: ?Bajo control del administrador. ?/cgi-bin ?Restringir el número de usuarios con acceso para incluir aplicaciones CGI. ?El CGI debería ejecutarse con los permisos de un usuario sin privilegios. ?Restringir los comandos de shell que puede ejecutar la aplicación CGI (Lenguaje: Shell-script). IST - 2006 Tema 3: CGI. CGI. 28 14 5. Seguridad Recomendaciones (II) ? Al programador CGI: ?Limitar en la medida de lo posible la ejecución de otros programas o comandos del SO. ?Cuando existen, vigilar que la entrada de datos del usuario no contiene símbolos con un significado especial (p.e: “/”, “..”, “*”, “|”, “>”, etc.). ?Crear CGI robustos, comprobando el funcionamiento ante entradas inesperadas. ?En lenguajes compilados, como C, se debe tener cuidado con el manejo de cadenas (con su longitud). ?No confiar en los caminos contenidos en las variables PATH, HTTP_REFERER , SCRIPT_NAME, PATH_INFO y PATH_TRANSLATED. IST - 2006 CGI. 29 6. Ejemplos de aplicaciones CGI Pagina Web con la hora y fecha actual #include <iostream> #include <ctime> using namespace std; int main () { time_t hora; time( &hora ); // Almacena la hora y fecha en la variable cout << "Content-Type: text/html" << endl << endl; cout << "<html><head>" << endl; cout << "<title>Fecha y Hora</title>" << endl; cout << "</head><body>" << endl; cout << "<p>Fecha y Hora actuales:"; cout << asctime(localtime(&hora)) << "</p>" << endl; cout << "</body></html>" << endl; return 0; } IST - 2006 Tema 3: CGI. CGI. 30 15 6. Ejemplos de aplicaciones CGI Imprime las variables de entorno (I) #include <string> #include <iostream> #include <cstdlib> using namespace std; int main () { string vEntorno[24] = { "DOCUMENT_ROOT", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", ... }; cout << "Content-Type: text/html" << endl << endl; cout << "<html><head><title>Variables de Entorno</title>"); cout << "</head><body>"<h2>Datos de entrada(método GET):</h2>"); cout << "QUERY_STRING:" << getenv("QUERY_STRING") << "<br>"; cout << "<h2>Todas las variables de entorno</h2>"); for ( i = 0; i < 24 ; i++ ) { cout << vEntorno[i] << ":"; cout << getenv(vEntorno[i].data()) << "<br>"; } cout << "</body></html>"); } IST - 2006 CGI. 31 6. Ejemplos de aplicaciones CGI Imprime las variables de entorno (II) IST - 2006 Tema 3: CGI. CGI. 32 16 6. Ejemplos de aplicaciones CGI Imprime las variables de entorno 2 Solicitud http://servidor/cgi-bin/micgi?usuario=pepe&edad=20 CGI "micgi.c" #include <stdio.h> void main(int argc,char *argv []) { printf("Content-type:text/plain \n \n") printf("Estas son algunas variables del entorno.\n \n"); printf("GATEWAY_INTERFACE =%s \n",getenv("GATEWAY_INTERFACE")); printf("HTTP_USER_AGENT =%s \n",getenv("HTTP_USER_AGENT")); printf("QUERY_STRING =%s \n",getenv("QUERY_STRING")); printf("REMOTE_ADDR =%s \n",getenv("REMOTE_ADDR")); printf("SERVER_SOFTWARE =%s \n",getenv("SERVER_SOFTWARE")); } IST - 2006 CGI. 33 6. Ejemplos de aplicaciones CGI Uso de la variable PATH_INFO ? La variable PATH_INFO contenía la URL relativa a ñadida a la dirección del CGI: http://www.uv.es/cgi-bin/fondo.cgi/fondos/img.jpg #include <iostream> using namespace std; int main () { int i; cout << "Content-Type: text/html\n\n"; cout << "<html><head>"; cout << "<title>Uso de PATH_INFO</title>"; cout << "</head>" << endl; cout << "<body background=" << getenv("PATH_INFO") << ">"; cout << "<h2>Ejemplo de uso de la variable PATH_INFO:</h2>"; ....... cout << "</body></html>"); return 0; } IST - 2006 CGI. 34 Tema 3: CGI. 17 6. Ejemplos de aplicaciones CGI Recoger datos de un formulario (I) #include <iostream> #include <string> #include <cstdlib> using namespace std; ... string DecodificaURL(string cad); void ParesVariableValor(string cadena, string var[MAX_ENTRIES], string val[MAX_ENTRIES], int &n); ... int main ( int argc, char *argv[] ) { string variables[MAX_ENTRIES], valores[MAX_ENTRIES], buffer_in; int ndatos, i, tam; printf("Content-type: text/html\n\n"); printf("<html><body>"); IST - 2006 CGI. 35 6. Ejemplos de aplicaciones CGI Recoger datos de un formulario (II) if ( strcmp(getenv("REQUEST_METHOD"), "POST")) { printf("Los datos deben ser enviados en modo POST"); printf("</html></body>"); exit(1); } if( strcmp( getenv("CONTENT_TYPE"), "application/x-www-form-urlencoded") ) { printf("Los datos deben estar codificados url-encoded"); printf("</html></body>"); exit(1); } tam = atoi(getenv("CONTENT_LENGTH")); cin.read( buffer_in, tam); IST - 2006 Tema 3: CGI. CGI. 36 18 6. Ejemplos de aplicaciones CGI Recoger datos de un formulario (III) ParesVariableValor(buffer_in, variables, valores, &ndatos); for (i =0; i< ndatos; i++) { variables[i] = DecodificaURL(variables[i]); valores[i] = DecodificaURL(valores[i]); } cout << "<h2>Datos enviados del formulario:</h2>"; cout << "<table align="center" border=3>"; cout << "<tr><th>Variable</th><th>Valor</th></tr>"; for ( i = 0; i < ndatos; i ++) { cout << "<hr><td>" << variables[i]; cout << "</td><td>" << valores[i] << "</td></tr>"; } cout "</table></body></html>"; } IST - 2006 Tema 3: CGI. CGI. 37 19