
En informática , Common Gateway Interface ( CGI ) es una especificación de interfaz que permite a los servidores web ejecutar un programa externo para procesar solicitudes de usuarios HTTP o HTTPS .
Estos programas suelen estar escritos en un lenguaje de script y se denominan comúnmente scripts CGI , pero pueden incluir programas compilados . [1]
Un caso de uso típico ocurre cuando un usuario web envía un formulario web en una página web que utiliza CGI. Los datos del formulario se envían al servidor web dentro de una solicitud HTTP con una URL que denota un script CGI. A continuación, el servidor web lanza el script CGI en un nuevo proceso informático , pasándole los datos del formulario. El script CGI pasa su salida, normalmente en forma de HTML , al servidor web, y el servidor la retransmite de nuevo al navegador como respuesta a la solicitud del navegador. [2]
Desarrollado a principios de los años 90, CGI fue el primer método común disponible que permitió que una página web fuera interactiva. Debido a la necesidad de ejecutar scripts CGI en un proceso independiente cada vez que llegaba una solicitud de un cliente, se desarrollaron varias alternativas.
Historia
En 1993, el equipo del Centro Nacional para Aplicaciones de Supercomputación (NCSA) escribió la especificación para llamar a ejecutables de línea de comandos en la lista de correo www-talk. [3] [4] [5] Los demás desarrolladores de servidores web la adoptaron y ha sido un estándar para servidores web desde entonces. Un grupo de trabajo presidido por Ken Coar comenzó en noviembre de 1997 para lograr que la definición de CGI de NCSA fuera definida de manera más formal. [6] Este trabajo dio como resultado el RFC 3875, que especificaba la versión 1.1 de CGI. En el RFC se mencionan específicamente los siguientes colaboradores: [2]
- Rob McCool (autor del servidor web HTTPd de NCSA )
- John Franks (autor del servidor web GN)
- Ari Luotonen (el desarrollador del servidor web httpd del CERN )
- Tony Sanders (autor del servidor web Plexus)
- George Phillips (responsable del mantenimiento del servidor web en la Universidad de Columbia Británica)
Históricamente, los programas CGI se escribían a menudo utilizando el lenguaje de programación C. RFC 3875 "La interfaz de puerta de enlace común (CGI)" define parcialmente CGI utilizando C, [2] al decir que las variables de entorno "se acceden mediante la rutina de biblioteca C getenv() o la variable environ".
El nombre CGI proviene de los primeros tiempos de la Web, cuando los webmasters querían conectar sistemas de información antiguos, como bases de datos, a sus servidores Web. El programa CGI era ejecutado por el servidor y proporcionaba una "puerta de enlace" común entre el servidor Web y el sistema de información antiguo.
Objetivo
Tradicionalmente, un servidor web tiene un directorio que se designa como una colección de documentos, es decir, un conjunto de archivos que se pueden enviar a los navegadores web conectados al servidor. [7] Por ejemplo, si un servidor web tiene el nombre de dominio completo www.example.com y su colección de documentos se almacena en el sistema de archivos/usr/local/apache/htdocs/ local (su raíz de documento ), entonces el servidor web responderá a una solicitud enviando al navegador una copia del archivo (si existe).
http://www.example.com/index.html/usr/local/apache/htdocs/index.html
Para las páginas construidas sobre la marcha, el software del servidor puede diferir las solicitudes a programas separados y transmitir los resultados al cliente solicitante (generalmente, un navegador web que muestra la página al usuario final).
Estos programas suelen requerir que se especifique alguna información adicional junto con la solicitud, como cadenas de consulta o cookies . Por el contrario, al regresar, el script debe proporcionar toda la información requerida por HTTP para una respuesta a la solicitud: el estado HTTP de la solicitud, el contenido del documento (si está disponible), el tipo de documento (por ejemplo, HTML, PDF o texto sin formato), etcétera.
Inicialmente, no existían métodos estandarizados para el intercambio de datos entre un navegador, el servidor HTTP con el que se comunicaba y los scripts del servidor que se esperaba que procesaran los datos y, en última instancia, devolvieran un resultado al navegador. Como resultado, existían incompatibilidades mutuas entre las diferentes variantes del servidor HTTP que socavaban la portabilidad de los scripts .
El reconocimiento de este problema condujo a la especificación de cómo se debía llevar a cabo el intercambio de datos, lo que dio lugar al desarrollo de CGI. Los programas generadores de páginas web invocados por el software de servidor que se adhiere a la especificación CGI se conocen como scripts CGI , aunque en realidad pueden haber sido escritos en un lenguaje que no sea de scripts, como C.
La especificación CGI fue adoptada rápidamente y continúa siendo compatible con todos los paquetes de servidores HTTP conocidos, como Apache , Microsoft IIS y (con una extensión) servidores basados en node.js.
Uno de los primeros usos de los scripts CGI fue procesar formularios. En los comienzos de HTML, los formularios HTML tenían normalmente un atributo "acción" y un botón designado como el botón "enviar". Cuando se pulsaba el botón de envío, la URI especificada en el atributo "acción" se enviaba al servidor con los datos del formulario enviados como una cadena de consulta. Si la "acción" especificaba un script CGI, este se ejecutaba y, a su vez, el script generaba una página HTML.
Despliegue
Un servidor Web que admita CGI puede configurarse para interpretar una URL que sirva como referencia a un script CGI. Una convención común es tener un cgi-bin/ directorio en la base del árbol de directorios y tratar todos los archivos ejecutables dentro de este directorio (y ningún otro, por seguridad) como scripts CGI. Cuando un navegador Web solicita una URL que apunta a un archivo dentro del directorio CGI (por ejemplo, http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=string), entonces, en lugar de simplemente enviar ese archivo ( /usr/local/apache/htdocs/cgi-bin/printenv.pl) al navegador Web, el servidor HTTP ejecuta el script especificado y pasa la salida del script al navegador Web. Es decir, todo lo que el script envía a la salida estándar se pasa al cliente Web en lugar de mostrarse en la ventana de terminal que inició el servidor Web. Otra convención popular es usar extensiones de nombre de archivo ; por ejemplo, si a los scripts CGI se les da constantemente la extensión .cgi, el servidor Web puede configurarse para interpretar todos esos archivos como scripts CGI. Si bien es conveniente y requerido por muchos scripts preempaquetados, abre el servidor a ataques si un usuario remoto puede cargar código ejecutable con la extensión adecuada.
La especificación CGI define cómo se pasa al script la información adicional que se pasa con la solicitud. El servidor web crea un subconjunto de las variables de entorno que se le pasan y añade detalles pertinentes al entorno HTTP. Por ejemplo, si se añaden una barra y nombres de directorio adicionales a la URL inmediatamente después del nombre del script (en este ejemplo, /with/additional/path), esa ruta se almacena en la PATH_INFO variable de entorno antes de que se llame al script. Si se envían parámetros al script mediante una solicitud HTTP GET (un signo de interrogación añadido a la URL, seguido de pares parámetro=valor; en el ejemplo, ?and=a&query=string), esos parámetros se almacenan en la QUERY_STRINGvariable de entorno antes de que se llame al script. El cuerpo del mensaje HTTP de la solicitud , como los parámetros de formulario enviados mediante una solicitud HTTP POST , se pasan a la entrada estándar del script . A continuación, el script puede leer estas variables de entorno o datos de la entrada estándar y adaptarse a la solicitud del navegador web. [8]
Usos
CGI se utiliza a menudo para procesar la información de entrada del usuario y producir la salida adecuada. Un ejemplo de un programa CGI es uno que implementa un wiki . Si el agente de usuario solicita el nombre de una entrada, el servidor web ejecuta el programa CGI. El programa CGI recupera la fuente de la página de esa entrada (si existe), la transforma en HTML e imprime el resultado. El servidor web recibe la salida del programa CGI y la transmite al agente de usuario. Luego, si el agente de usuario hace clic en el botón "Editar página", el programa CGI llena un HTML textareau otro control de edición con el contenido de la página. Finalmente, si el agente de usuario hace clic en el botón "Publicar página", el programa CGI transforma el HTML actualizado en la fuente de la página de esa entrada y lo guarda.
Seguridad
Los programas CGI se ejecutan, de forma predeterminada, en el contexto de seguridad del servidor web. Cuando se introdujeron por primera vez, se proporcionaron varios scripts de ejemplo con las distribuciones de referencia de los servidores web NCSA, Apache y CERN para mostrar cómo se podían codificar scripts de shell o programas C para utilizar el nuevo CGI. Uno de esos scripts de ejemplo era un programa CGI llamado PHF que implementaba una guía telefónica sencilla.
Al igual que muchos otros scripts de la época, este utilizaba una función: escape_shell_cmd(). Se suponía que la función debía sanear su argumento, que provenía de la entrada del usuario y luego pasar la entrada al shell de Unix, para que se ejecutara en el contexto de seguridad del servidor web. El script no saneaba correctamente toda la entrada y permitía que se pasaran nuevas líneas al shell, lo que efectivamente permitía ejecutar varios comandos. Los resultados de estos comandos se mostraban luego en el servidor web. Si el contexto de seguridad del servidor web lo permitía, los atacantes podían ejecutar comandos maliciosos.
Este fue el primer ejemplo generalizado de un nuevo tipo de ataque basado en la Web llamado inyección de código , en el que datos no saneados de usuarios de la Web podían llevar a la ejecución de código en un servidor Web. Debido a que el código de ejemplo se instalaba de forma predeterminada, los ataques se generalizaron y dieron lugar a una serie de avisos de seguridad a principios de 1996. [9]
Alternativas
Para cada solicitud HTTP entrante, un servidor web crea un nuevo proceso CGI para procesarla y destruye el proceso CGI una vez procesada la solicitud HTTP. La creación y destrucción de un proceso puede consumir más tiempo de CPU y recursos de memoria que el trabajo real de generar la salida del proceso, especialmente cuando el programa CGI aún necesita ser interpretado por una máquina virtual. Para una gran cantidad de solicitudes HTTP, la carga de trabajo resultante puede saturar rápidamente el servidor web.
La sobrecarga computacional involucrada en la creación y destrucción de procesos CGI se puede reducir mediante las siguientes técnicas:
- Programas CGI precompilados en código máquina , por ejemplo, precompilados a partir de programas C o C++ , en lugar de programas CGI ejecutados por un intérprete, por ejemplo, programas Perl , PHP o Python .
- Extensiones de servidor web como módulos Apache (por ejemplo
mod_perl, ,mod_phpymod_python), complementos NSAPI y complementos ISAPI que permiten que procesos de aplicaciones de larga ejecución manejen más de una solicitud y estén alojados dentro del servidor web. - FastCGI , SCGI y AJP permiten que los procesos de aplicación de larga duración que manejan más de una solicitud se alojen externamente, es decir, por separado del servidor web. Cada proceso de aplicación escucha en un socket; el servidor web maneja una solicitud HTTP y la envía a través de otro protocolo (FastCGI, SCGI o AJP) al socket solo para contenido dinámico, mientras que el contenido estático generalmente lo maneja directamente el servidor web. Este enfoque necesita menos procesos de aplicación, por lo que consume menos memoria que el enfoque de extensión del servidor web. Y a diferencia de la conversión de un programa de aplicación en una extensión del servidor web, los programas de aplicación FastCGI, SCGI y AJP permanecen independientes del servidor web.
- Jakarta EE ejecuta aplicaciones Jakarta Servlet en un contenedor web para ofrecer contenido dinámico y, opcionalmente, contenido estático, lo que reemplaza la sobrecarga de crear y destruir procesos por la sobrecarga mucho menor de crear y destruir subprocesos . También expone al programador a la biblioteca que viene con Java SE en la que se basa la versión de Jakarta EE en uso.
- Servidor HTTP independiente
- La interfaz de puerta de enlace del servidor web (WSGI) es un enfoque moderno escrito en el lenguaje de programación Python . Está definida en PEP 3333 [10] y se implementa a través de varios métodos como
mod_wsgi(módulo Apache), servidor web Gunicorn (entre Nginx y scripts/marcos como Django), UWSGI , etc.
La configuración óptima para cualquier aplicación web depende de los detalles específicos de la aplicación, la cantidad de tráfico y la complejidad de la transacción; es necesario analizar estas ventajas y desventajas para determinar la mejor implementación para una tarea y un presupuesto de tiempo determinados. Los marcos web ofrecen una alternativa al uso de scripts CGI para interactuar con los agentes de usuario.
Véase también
- CGI.pm – Módulo Perl para programar aplicaciones web Common Gateway Interface (CGI)Páginas que muestran descripciones de wikidata como alternativa
- Interfaz de puerta de enlace DOS : navegador web gráfico para DOS y LinuxPáginas que muestran descripciones breves de los objetivos de redireccionamiento
- Interfaz de puerta de enlace de servidor web Perl : marco de aplicación webPáginas que muestran descripciones de wikidata como alternativa
- Rack (interfaz de servidor web) : especificación API para aplicaciones web en lenguaje de programación Ruby
- Server Side Includes : lenguaje de programación del lado del servidor interpretado
Referencias
- ^ Robinson <drtr@apache.org>, David (2004). "The Common Gateway Interface (CGI) Version 1.1". tools.ietf.org . doi :10.17487/RFC3875. Archivado desde el original el 11 de febrero de 2007 . Consultado el 16 de febrero de 2021 .
- ^ abc Robinson, D.; Coar, K. (2004). «RFC3875: La interfaz de puerta de enlace común (CGI) versión 1.1». doi :10.17487/RFC3875. Archivado desde el original el 19 de abril de 2021. Consultado el 25 de febrero de 2012 .
{{cite journal}}: Requiere citar revista|journal=( ayuda ) - ^ McCool, Rob (14 de noviembre de 1993). "Server Scripts". www-talk (Lista de correo) . Consultado el 15 de mayo de 2019 .
- ^ "La interfaz de puerta de enlace común". hoohoo.ncsa.uiuc.edu . Centro Nacional para Aplicaciones de Supercomputación (NCSA). Archivado desde el original el 27 de enero de 2010.
- ^ "CGI: Common Gateway Interface". w3.org . Consorcio World Wide Web. Archivado desde el original el 19 de diciembre de 2009 . Consultado el 15 de mayo de 2019 .
- ^ "Página del proyecto RFC de interfaz de puerta de enlace común". Archivado desde el original el 25 de agosto de 2013.
- ^ "Asignación de direcciones URL a ubicaciones del sistema de archivos en Apache HTTP Server versión 2.2". Archivado desde el original el 15 de julio de 2014 . Consultado el 16 de julio de 2014 .
- ^ Nelson, Anne Fulcher y Nelson, William Harris Morehead. (2001). Creación de comercio electrónico con construcciones de bases de datos web. Boston, MA: Addison Wesley.
- ^ "El script CGI phf no protege contra los caracteres de nueva línea". Centro de coordinación CERT del Instituto de ingeniería de software . Archivado desde el original el 28 de julio de 2020. Consultado el 21 de noviembre de 2019 .
- ^ "PEP 3333 – Interfaz de puerta de enlace de servidor web Python v1.0.1 | peps.python.org". Propuestas de mejora de Python (PEP) . Consultado el 5 de abril de 2024 .
Enlaces externos
- La invención de CGI
- Programación CGI 101: ¡Aprenda CGI hoy!, un tutorial de CGI