공통 게이트웨이 인터페이스
Common Gateway Interface컴퓨팅에서 Common Gateway Interface(CGI; 공통 게이트웨이 인터페이스)[1]는 웹 서버가 일반적으로 사용자 요청을 처리하는 외부 프로그램을 실행할 수 있도록 하는 인터페이스 사양입니다.
이러한 프로그램은 스크립트 언어로 작성되어 CGI 스크립트라고 불리는 경우가 많지만 컴파일된 [2]프로그램을 포함할 수도 있습니다.
일반적인 사용 사례는 웹 사용자가 CGI를 사용하는 웹 페이지에 웹 양식을 제출할 때 발생합니다.양식의 데이터는 CGI 스크립트를 나타내는 URL과 함께 HTTP 요청 내의 웹 서버로 전송됩니다.그런 다음 웹 서버는 새 시스템 프로세스에서 CGI 스크립트를 시작하고 양식 데이터를 전달합니다.CGI 스크립트의 출력은 보통 HTML 형식으로 스크립트에 의해 웹 서버로 반환되고 서버는 브라우저 [3]요청에 대한 응답으로 브라우저에 다시 릴레이합니다.
1990년대 초에 개발된 CGI는 웹 페이지를 인터랙티브하게 만들 수 있는 가장 초기의 일반적인 방법이었다.
역사
1993년 NCSA(National Center for Supercomputing Applications) 팀은 www-talk 메일링 [4][5][6]목록에 명령줄 실행 파일의 호출 사양을 작성했습니다.다른 웹 서버 개발자들이 그것을 채택했고, 그 이후로 웹 서버의 표준이 되었다.Ken Coar가 의장을 맡은 작업 그룹은 CGI의 NCSA 정의를 [7]더 공식적으로 정의하기 위해 1997년 11월에 시작되었습니다.이 작업을 통해 CGI 버전 1.1을 지정한 RFC 3875가 작성되었습니다.RFC에 구체적으로 기재되어 있는 [3]것은, 다음의 요인입니다.
- Rob McCool(NCSA HTTPd 웹 서버 작성자)
- John Franks(GN 웹 서버 작성자)
- Ari Luotonen(CERN httpd 웹 서버 개발자)
- Tony Sanders (Plexus Web 서버 저자)
- George Phillips(브리티시컬럼비아대학 웹 서버 유지보수 담당)
지금까지 CGI 프로그램은 종종 C 프로그래밍 언어를 사용하여 작성되었습니다.RFC 3875 "Common Gateway Interface (CGI)"는 환경변수가 "C 라이브러리 루틴 getenv() 또는 가변환경에 의해 접근된다"는 점에서 부분적으로 [3]C를 사용하여 CGI를 정의하고 있습니다.
CGI라는 이름은 웹 마스터가 데이터베이스와 같은 레거시 정보 시스템을 웹 서버에 연결하려고 했던 웹 초창기에서 유래했습니다.CGI 프로그램은 웹 서버와 레거시 정보 시스템 간에 공통의 "게이트웨이"를 제공하는 서버에 의해 실행되었습니다.
CGI 사양의 목적
각 웹 서버는 웹 브라우저의 요청에 응답하는 HTTP 서버 소프트웨어를 실행합니다.일반적으로 HTTP 서버에는 문서 모음으로 지정된 디렉토리(폴더)가 있습니다. 이 폴더는 [8]이 서버에 연결된 웹 브라우저로 전송할 수 있는 파일입니다.예를 들어 웹 서버에 도메인 이름이 있는 경우example.com
문서 모음은 다음 위치에 저장됩니다./usr/local/apache/htdocs/
로컬 파일 시스템에서 웹 서버는 다음 요구에 응답합니다.http://example.com/index.html
(사전 작성된) 파일을 브라우저로 전송하여/usr/local/apache/htdocs/index.html
.
즉석에서 작성된 페이지의 경우, 서버 소프트웨어는 개별 프로그램에 대한 요구를 지연시키고, 그 결과를 의뢰하는 클라이언트(일반적으로 최종 사용자에게 페이지를 표시하는 웹 브라우저)에 릴레이할 수 있습니다.웹의 초창기에는 이러한 프로그램들이 보통 작고 스크립트 언어로 작성되었기 때문에 스크립트라고 불렸습니다.
이러한 프로그램에서는 보통 요청과 함께 몇 가지 추가 정보를 지정해야 합니다.예를 들어 Wikipedia가 스크립트로 구현되어 있는 경우 스크립트는 사용자가 로그인하고 있는지 여부와 로그인하고 있는 경우 어떤 이름으로 로그인하고 있는지 알아야 합니다.Wikipedia 페이지 상단에 있는 내용은 이 정보에 따라 달라집니다.
HTTP는 브라우저가 이러한 정보를 URL의 일부로 웹 서버에 전달하는 방법을 제공합니다.그런 다음 서버 소프트웨어는 이 정보를 스크립트에 전달해야 합니다.
반대로 반환 시 스크립트는 요청에 대한 응답에 필요한 HTTP 상태, 문서 내용(사용 가능한 경우), 문서 유형(HTML, PDF, 일반 텍스트 등)을 모두 제공해야 합니다.
처음에는 서버 소프트웨어마다 이 정보를 스크립트와 교환하는 방법이 다릅니다.그 결과 교환되는 정보가 동일하더라도 서로 다른 서버 소프트웨어에 대해 수정 없이 작동하는 스크립트를 작성할 수 없었습니다.따라서 이 정보를 교환하는 방법을 CGI(서버 소프트웨어가 스크립트와 인터페이스하는 일반적인 방법을 정의하기 때문에 공통 게이트웨이 인터페이스)로 지정하기로 결정했습니다.CGI 사양에 따라 작동하는 서버 소프트웨어에 의해 호출되는 웹 페이지 생성 프로그램을 CGI 스크립트라고 합니다.
이 사양은 빠르게 채택되어 Apache, IIS 및 (확장기능이 있는) node.js 기반 서버 등 잘 알려진 모든 서버 소프트웨어에서 여전히 지원됩니다.
CGI 스크립트의 초기 용도는 폼 처리였습니다.HTML의 시작 부분에서 HTML 양식에는 일반적으로 "수행" 속성과 "제출" 버튼으로 지정된 버튼이 있습니다.[ Submit ]버튼을 누르면 "action" 속성으로 지정된 URI가 쿼리 문자열로 전송된 형식의 데이터와 함께 서버로 전송됩니다."action"이 CGI 스크립트를 지정하면 CGI 스크립트가 실행되고 HTML 페이지가 생성됩니다.
CGI 스크립트 사용
웹 서버에서는 소유자가 어떤 CGI 스크립트에서 어떤 URL을 처리할지를 설정할 수 있습니다.
이것은 보통 문서 컬렉션 내의 새로운 디렉토리를 CGI 스크립트가 포함되어 있는 것으로 마크함으로써 이루어집니다.대부분 그 이름은cgi-bin
.예를들면,/usr/local/apache/htdocs/cgi-bin
웹 서버의 CGI 디렉토리로 지정할 수 있습니다.웹 브라우저가 CGI 디렉토리 내의 파일을 가리키는 URL을 요구할 때(예:http://example.com/cgi-bin/printenv.pl/with/additional/path?and=a&query=string
그럼 단순히 파일을 보내는 것이 아니라/usr/local/apache/htdocs/cgi-bin/printenv.pl
)는 HTTP 서버가 지정된 스크립트를 실행하여 스크립트의 출력을 웹 브라우저에 전달합니다.즉, 스크립트가 표준 출력으로 전송하는 모든 것은 터미널 창에 화면에 표시되지 않고 웹 클라이언트에 전달됩니다.
전술한 바와 같이 CGI 사양은 요구와 함께 전달된 추가 정보가 스크립트에 전달되는 방법을 정의합니다.예를 들어 스크립트의 이름 바로 뒤에 슬래시와 추가 디렉토리 이름이 URL에 추가된 경우(이 예에서는/with/additional/path
), 그 패스는 에 저장됩니다.PATH_INFO
환경변수를 선택합니다.파라미터가 HTTP GET 요구를 통해 스크립트로 전송되는 경우(URL에 물음표가 추가된 후 param=값 쌍이 이어집니다.이 예에서는,?and=a&query=string
)의 경우 이들 파라미터는 에 파라미터가 저장됩니다.QUERY_STRING
환경변수를 선택합니다.파라미터가 HTTP POST 요청을 통해 스크립트로 전송되면 파라미터는 스크립트의 표준 입력으로 전달됩니다.그러면 스크립트는 표준 입력에서 이러한 환경 변수 또는 데이터를 읽고 웹 브라우저의 요청에 [9]맞게 조정할 수 있습니다.
예
다음 Perl 프로그램은 웹 서버에 의해 전달된 모든 환경 변수를 표시합니다.
#!/usr/bin/env perl =head1 설명 printenv - 환경을 인쇄하는 CGI 프로그램 =컷 인쇄물 "Content-Type: 텍스트/일반\n\n"; 위해서 나의 $var ( 종류 열쇠들. %ENV ) { 인쇄물 %s=\"%s\n", $var, 엔비{$var}; }
웹 브라우저가 환경변수에 대한 요청을 발행하는 경우:http://example.com/cgi-bin/printenv.pl/foo/bar?var1=value1&var2=with%20percent%20encoding
cygwin을 실행하는 64비트 Windows 7 웹 서버는 다음 정보를 반환합니다.
COMSPEC="C:\Windows\system32\cmd.exe" DOCUMENT_ROOT="C:/프로그램 파일(x86)/Apache 소프트웨어 Foundation/Apache2.4/htdocs" GATEWAY_INTERFACE=" CGI/1.1" HOME="/html, application/xml, application/xml, q= 0.9,*;q= 0.8" HTTP_ACCEPT_CHERSET="/SYSTEM"ISO-8859-1, utf-8;q=0.7,*;q=0.7" HTTP_ACCEPT_ENCODING="gzip, deflate, br" HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5" HTTP_CONNECTION="-alive" HTTP_HOST="」 「 PATHEXT 。COM;.EXE;.BAT;.CMD;.VBS;VBE;.JS;JSE;.WSF;WSH;.MSC" PATH_INFO="/foo/bar" PATH_TRANSLATED="C:\Program Files (x86)\Apache Software Foundation\Apache2.4\htdocs\foo\bar"QUERY_STRING="var1=value1&, var2=with% 달하는%20encoding"REMOTE_ADDR="127.0.0.1"REMOTE_PORT="63555"REQUEST_METHOD="GET"REQUEST_URI="/cgi-bin/printenv.pl/foo/bar?var1=value1&, var2=with% 달하는%20encoding"SCRIPT_FILENAME="C:/Program 파일(x86)/Apache 소프트웨어 Foundation/Apache2.4/cgi-bin"SCRIPT_NAME="/cgi.-bin/printenv.pl" SERVER_ADDR="127.0.0.1" SERVER_ADMIN=(서버 관리자의 이메일 주소)" SERVER_NAME="127.0.0.1" SERVER_PORT="80" SERVER_PROTOCol="HTTP/1.1" SERVER_시그니처=" SERVER_SOFTWARE="Apache/2.4.39(Win32) PHP/7.3.7" SYSTEMROOT="C:\Windows" TERM="cygwin" WINDIR="C:\Windows"
이러한 변수 중 일부는 CGI 표준에 의해 정의되지만 전부는 아닙니다.예를 들어 다음과 같은 것들이 있습니다.PATH_INFO
,QUERY_STRING
, 및 로 시작하는 것HTTP_
는 HTTP 요청에서 정보를 전달합니다.
환경에서 웹 브라우저가 Windows 7 PC에서 실행되고 있는 Firefox, 웹 서버가 Unix를 에뮬레이트하는 시스템에서 실행되고 있는 Apache, CGI 스크립트가 명명된 것을 알 수 있습니다.cgi-bin/printenv.pl
.
그러면 프로그램은 콘텐츠를 생성하여 표준 출력에 쓰고 웹 서버가 브라우저로 전송합니다.
CGI 프로그램에 전달되는 환경변수는 다음과 같습니다.
- 서버 고유 변수:
- 특정 변수 요청:
SERVER_PROTOCOL
: HTTP/version.SERVER_PORT
: TCP 포트(10 진수).REQUEST_METHOD
: HTTP 메서드 이름(위 참조).PATH_INFO
: 경로 서픽스(프로그램 이름 및 슬래시 뒤에 URL에 추가되는 경우).PATH_TRANSLATED
: 서버에서 상정되는 풀 패스에 대응합니다.PATH_INFO
존재합니다.SCRIPT_NAME
: 프로그램에 대한 상대 경로, 예를 들어 다음과 같습니다./cgi-bin/script.cgi
.QUERY_STRING
: ? 문자 뒤의 URL 부분.쿼리 문자열은 *로 구성될 수 있습니다.name=value앰퍼샌드로 분리된 쌍(예:var1=val1&var2=val2...) HTML 어플리케이션/x-www-form-urlencoded에서 정의된 대로 GET 메서드로 전송된 폼 데이터를 전송하기 위해 사용됩니다.REMOTE_HOST
: 클라이언트의 호스트명.서버가 이러한 조회를 실행하지 않은 경우 설정되지 않습니다.REMOTE_ADDR
: 클라이언트의 IP 주소(도트 10 진수).AUTH_TYPE
: 식별 유형(해당하는 경우).REMOTE_USER
확실히 사용되다AUTH_TYPE
s.REMOTE_IDENT
: 서버가 이러한 조회를 실행한 경우에만 ID를 확인합니다.CONTENT_TYPE
: HTTP 헤더를 통해 제공되는 PUT 또는 POST 방식을 사용하는 경우 입력 데이터의 인터넷 미디어 유형.CONTENT_LENGTH
: 마찬가지로 HTTP 헤더를 통해 제공되는 경우 입력 데이터의 크기(10진수, 옥텟 단위).- 사용자 에이전트에 의해 전달된 변수(
HTTP_ACCEPT
,HTTP_ACCEPT_LANGUAGE
,HTTP_USER_AGENT
,HTTP_COOKIE
및 기타)에는 대응하는 HTTP 헤더 값이 포함되어 있기 때문에 같은 의미를 가집니다.
프로그램은 결과를 표준 출력 형식으로 헤더와 공백 행으로 시작하여 웹 서버에 반환합니다.
헤더는 HTTP 헤더와 동일한 방식으로 인코딩되며 [10]반환된 문서의 MIME 유형을 포함해야 합니다.웹 서버에 의해 보완되는 헤더는 일반적으로 사용자에게 응답과 함께 전달됩니다.
다음은 간단한 추가 [11]문제를 처리하는 HTML과 함께 파이썬 3으로 작성된 간단한 CGI 프로그램입니다.
add.html
:
<!DO3}PE html> <body> <폼 작업="add.cgi" 메서드="POST"> <필드셋> <레전드>추가할 2개의 번호를 입력합니다.< / legend > < label >첫 번째 번호: <input type="number" name="num1"> </label> <br/> <label>두 번째 번호: <input type="number" name="num2"> </label> </br/> </fieldset> </button> </form> </body> </body>
add.cgi
:
#!/usr/bin/env python3 수입품 cgi, cgitb cgitb.가능하게 하다() 입력_데이터 = cgi.필드 스토리지() 인쇄물('Content-Type: text/html') # HTML이 팔로우 하고 있다 인쇄물('') # 공백으로 남겨주세요 인쇄물('추가 결과' </h1>) 해라: 숫자 1 = 인트(입력_데이터["num1"].가치) 숫자 2 = 인트(입력_데이터["num2"].가치) 제외하고: 인쇄물('<출력>죄송합니다. 입력 내용을 숫자(정수)로 변환할 수 없습니다.</output>') 올리다 시스템 종료(1) 인쇄물('<출력>{0}+{1}={2}</output>'.포맷(숫자 1, 숫자 2, 숫자 1 + 숫자 2))
이 Python 3 CGI 프로그램은 HTML에서 입력을 받아 두 숫자를 합산합니다.
도입
CGI 를 서포트하는 Web 서버는, CGI 스크립트에 대한 참조로서 기능하는 URL 를 해석하도록 설정할 수 있습니다.일반적인 관례는 다음과 같습니다.cgi-bin/
디렉토리 트리의 베이스에 있는 디렉토리로, 이 디렉토리내의 모든 실행 가능 파일(보안상의 경우는 제외)을 CGI 스크립트로 취급합니다.또 하나의 일반적인 규칙은 파일 이름 확장자를 사용하는 것입니다.예를 들어 CGI 스크립트에 항상 확장자가 지정되어 있는 경우.cgi
이러한 모든 파일을 CGI 스크립트로 해석하도록 웹 서버를 설정할 수 있습니다.많은 사전 패키징된 스크립트에서 편리하고 필수적이지만 리모트 사용자가 적절한 확장자로 실행 가능한 코드를 업로드할 수 있는 경우 서버를 열어 공격합니다.
HTTP PUT 또는 POST의 경우 사용자가 제출한 데이터는 표준 입력을 통해 프로그램에 제공됩니다.웹 서버는 전달된 환경 변수의 서브셋을 생성하고 HTTP 환경과 관련된 세부 정보를 추가합니다.
사용하다
CGI는 사용자로부터의 입력 정보를 처리하고 적절한 출력을 생성하기 위해 자주 사용됩니다.CGI 프로그램의 예로는 Wiki를 구현하는 프로그램이 있습니다.사용자 에이전트가 엔트리의 이름을 요구하면 웹 서버는 CGI 프로그램을 실행합니다.CGI 프로그램은 엔트리의 페이지 소스(존재하는 경우)를 가져와 HTML로 변환하고 결과를 인쇄합니다.웹 서버는 CGI 프로그램에서 출력을 수신하여 사용자 에이전트에 전송합니다.그런 다음 사용자 에이전트가 "Edit page" 버튼을 클릭하면 CGI 프로그램이 HTML을 채웁니다.textarea
또는 페이지 내용을 포함한 기타 편집 제어.마지막으로 사용자 에이전트가 "페이지 게시" 단추를 클릭하면 CGI 프로그램이 업데이트된 HTML을 해당 항목의 페이지 소스로 변환하여 저장합니다.
보안.
CGI 프로그램은 기본적으로 웹 서버의 보안 컨텍스트에서 실행됩니다.NCSA, Apache 및 CERN 웹 서버의 참조 배포와 함께 다수의 예제 스크립트가 제공되어 새로운 CGI를 사용하기 위해 셸 스크립트 또는 C 프로그램을 코드화하는 방법을 보여 줍니다.그러한 스크립트 중 하나는 간단한 전화번호부를 구현하는 PHF라고 불리는 CGI 프로그램입니다.
당시 다른 많은 스크립트와 마찬가지로 이 스크립트는 다음 함수를 사용했습니다.escape_shell_cmd()
함수는 사용자 입력에서 가져온 인수를 삭제한 후 입력을 Unix 쉘로 전달하여 웹 서버의 보안 컨텍스트에서 실행하도록 되어 있습니다.스크립트에 의해 모든 입력이 올바르게 삭제되지 않고 셸에 새로운 행을 전달할 수 있게 되어 여러 명령을 실행할 수 있게 되었습니다.그런 다음 이러한 명령어의 결과가 웹 서버에 표시됩니다.웹 서버의 보안 컨텍스트가 이를 허용하는 경우 공격자가 악의적인 명령을 실행할 수 있습니다.
이는 웹 사용자의 비위생화된 데이터가 웹 서버에서 코드를 실행할 수 있는 새로운 유형의 웹 기반 공격의 첫 번째 광범위한 예입니다.이 샘플 코드는 디폴트로 인스톨 되어 있기 때문에, 공격이 광범위하게 행해졌고,[12] 1996년 초에 다수의 시큐러티 어드바이저가 발행되었습니다.
대체 수단
Web 서버는, 착신 HTTP 요구 마다, 그 처리를 위한 새로운 CGI 프로세스를 작성해, HTTP 요구가 처리된 후에 CGI 프로세스를 파기합니다.프로세스 생성 및 파괴는 프로세스 출력을 생성하는 실제 작업보다 훨씬 더 많은 CPU와 메모리를 소모할 수 있습니다. 특히 CGI 프로그램을 가상 머신에서 해석해야 하는 경우에는 더욱 그렇습니다.HTTP 요청 수가 많을 경우 결과 워크로드가 웹 서버를 빠르게 압도할 수 있습니다.
CGI 프로세스의 작성과 파괴에 수반하는 오버헤드는, 다음의 방법으로 삭감할 수 있습니다.
- 가상 머신에 의해 해석되는 CGI 프로그램(예: Perl, PHP 또는 Python 프로그램)이 아닌 C 또는 C++ 프로그램에서 미리 컴파일된 CGI 프로그램(예: C 또는 C++ 프로그램)으로 미리 컴파일된 CGI 프로그램.
- Apache 모듈(mod_perl, mod_php, mod_python 등), NSAPI 플러그인 및 ISAPI 플러그인 등의 웹 서버 확장 기능을 통해 여러 요청을 처리하고 웹 서버 내에서 호스팅할 수 있습니다.Web 2.0을 사용하면 HTML 폼을 사용하지 않고 사용자가 눈치채지 [13]못하게 클라이언트에서 서버로 데이터를 전송할 수 있습니다.
- FastCGI, SCGI 및 AJP를 사용하면 웹 서버에 대해 외부에서 호스트되는 여러 요청을 장기간 실행 중인 응용 프로그램 프로세스가 처리할 수 있습니다.각 응용 프로그램 프로세스는 소켓에서 수신합니다.웹 서버는 HTTP 요청을 처리하고 동적 콘텐츠에 대해서만 다른 프로토콜(FastCGI, SCGI 또는 AJP)을 통해 소켓으로 전송합니다.일반적으로 정적 콘텐츠는 웹 서버에 의해 직접 처리됩니다.이 접근방식은 어플리케이션프로세스가 적게 필요하기 때문에 웹 서버 확장 접근방식보다 메모리를 적게 소비합니다.또한 응용 프로그램을 웹 서버 확장으로 변환하는 것과 달리 Fast CGI, SCGI 및 AJP 응용 프로그램은 웹 서버로부터 독립되어 있습니다.
- 자카르타 EE는 웹 컨테이너에서 자카르타 Servlet 응용 프로그램을 실행하여 동적 콘텐츠와 선택적으로 정적 콘텐츠를 제공합니다. 정적 콘텐츠는 프로세스 생성 및 파괴의 오버헤드를 훨씬 낮은 스레드 생성 및 파괴의 오버헤드로 대체합니다.또한 사용 중인 자카르타 EE 버전이 기반인 Java SE와 함께 제공되는 라이브러리에 프로그래머를 노출합니다.
웹 응용 프로그램에 대한 최적의 구성은 응용 프로그램 고유의 세부 정보, 트래픽 양 및 트랜잭션의 복잡성에 따라 달라집니다. 이러한 트레이드오프를 분석하여 주어진 작업 및 시간 예산에 가장 적합한 구현을 결정해야 합니다.웹 프레임워크는 CGI 스크립트를 사용하여 사용자 에이전트와 대화하는 대신 사용할 수 있습니다.
「 」를 참조해 주세요.
레퍼런스
- ^ Robinson <drtr@apache.org>, David. "The Common Gateway Interface (CGI) Version 1.1". tools.ietf.org. Retrieved 16 February 2021.
- ^ Robinson <drtr@apache.org>, David. "The Common Gateway Interface (CGI) Version 1.1". tools.ietf.org. Archived from the original on 11 February 2007. Retrieved 16 February 2021.
- ^ a b c "RFC3875: The Common Gateway Interface (CGI) Version 1.1".
- ^ McCool, Rob (November 14, 1993). "Server Scripts". www-talk (Mailing list). Retrieved 2019-05-15.
- ^ "The Common Gateway Interface". hoohoo.ncsa.uiuc.edu. National Center for Supercomputing Applications (NCSA). Archived from the original on 27 January 2010.
- ^ "CGI: Common Gateway Interface". w3.org. World Wide Web Consortium. Retrieved 2019-05-15.
- ^ "Common Gateway Interface RFC Project Page". Archived from the original on 25 August 2013.
- ^ "Mapping URLs to Filesystem Locations Apache HTTP Server Version 2.2".
- ^ 넬슨, 앤 풀처, 그리고 넬슨, 윌리엄 해리스 모어헤드.(2001).Web Database Constructions를 통한 전자상거래 구축.보스턴, 매사추세츠: 애디슨 웨슬리
- ^ "CGI Primer (Mirror at citycat.ru)".
- ^ "Abacles HTML Forms". www.abacles.com. Archived from the original on 19 April 2016. Retrieved 6 April 2016.
- ^ "phf CGI Script fails to guard against newline characters". Software Engineering Institute CERT Coordination Center. Retrieved 21 November 2019.
- ^ Enrico Marino (11 September 2018). Information Management in the Distributed Web (PDF) (phd). Roma Tre University. Retrieved 11 February 2019.