CGI

22.11.1998
Markus Kolsi
Tietotekniikan osasto
Teknillinen Korkeakoulu
markus.kolsi@hut.fi

Tiivistelmä

CGI eli Common Gateway Interface tarkoittaa käytäntöä, jolla voidaan ajaa verkkopalvelimella olevia ohjelmia ja tulostaa ohjelman syöte asiakaskoneelle. Sovelluksena voi olla esimerkiksi verkkosivulla oleva laskuri. CGI ohjelmointikieli voi olla joko skriptikieli tai tavallinen ohjelmointikieli. Yleisin CGI skriptikieli on PERL. CGI:n käyttö yliopistoilla oman kotisivun yhteydessä on yleensä kielletty, koska ohjelmien ajaminen muodostaa tietoturvariskin. Palvelin ja CGI skripti kommunikoivat neljällä eri tavalla, joita on ympäristömuuttujat, komentorivi, standardi syöttö ja standari ulostulo. Ympäristömuuttujia CGI käyttää parametrien välitykseen ohjelmalle.


1 Johdanto

CGI tulee sanoista Common Gateway Interface ja se on standardirajapinta verkkopalvelinten (HTTP) ulkoisille sovelluksille. CGI-ohjelman ajo tapahtuu palvelimelta reaaliaikaisesti ja ohjelma voi tulostaa dynaamista informaatiota, kuten hakuja palvelimen tietokannasta. Ajettaessa WWW-sivun yhteydessä olevaa CGI-ohjelmaa, on siis mahdollista tehdä esimerkiksi tietokantahakuja palvelimen tietokantaan ja tulostaa hakujen tulokset asiakkaalle. CGI-ohjelman ajaa verkkodemoni eli httpd (hypertext transfer protocol daemon).[1]

2 Yleisimmät sovellukset

Yleisin verkon CGI-sovellus lienee laskuri, joka yrittää pitää kirjaa WWW-sivulla käynneistä. Muita yleisiä CGI-sovelluksia ovat sähköpostiautomaatit, vieraskirjat sekä dokumentteihin kohdistuvat haut.

3 Tavallisimmat CGI-ohjelmoinnissa käytettävät kielet

CGI-ohjelmoinnissa käytettävät ohjelmointikielet jakaantuvat skriptikieliin sekä tavallisiin ohjelmointikieliin. Tunnetuimpia CGI-skriptikieliä ovat Unix-shelliskripti (sh, ksh, csh jne.), TCL, Python ja Perl. Ohjelmointikielistä yleisimmät CGI-ohjelmoinnissa ovat C ja C++. Käytännössä CGI-ohjelma voi olla kirjoitettu millä tahansa kielellä, joka sallii ohjelman ajamisen systeemissä. Mikäli kirjoittaa CGI-skriptejä CGI-ohjelmien asemesta, on etuna skriptin debukkauksen helppous ja skriptin muuttaminen, koska erillistä kääntämistä ei tarvitse. [1]

Perl on erittäin yleisesti käytössä oleva CGI-skriptiohjelmointikieli. Perlin käyttötarkoituksia on lukuisia, joista tyypillisimpiä on mm. tiedon hakeminen tekstitiedostosta tai tekstitiedoston muuntaminen toiseen muotoon. Perlillä kirjoitettuja ohjelmia kutsutaan Perl skripteiksi ja perl on tulkattava kieli, joten perl skriptien ajaminen on hitaampaa kuin esimerkiksi C-ohjelmien.

Eräs yksinkertaisimmista mahdollisista Perl-skripteistä voisi tulostaa vaikka "Terve maailma". Perl-skripti, joka tulostaa tämän on seuraava:

#!/usr/bin/perl
print "Terve maailma\n";

Ohjelman ensimmäinen rivi kertoo, että kyseessä on Perl-skripti. Kun ohjelma on talletettu esimerkiksi tiedostoksi "terve" ja tiedoston suojaukset ovat oikein (chmod a+x terve), voidaan ohjelma ajaa seuraavasti:

./terve

[3]

4 Tietoturvakysymykset

Mikäli verkkopalvelimella oleva CGI-ohjelma on koko maailman ajettavissa, tarkoittaa tämä sitä, että kuka tahansa ohjelman suorittaja rasittaa palvelinta ajamalla CGI-ohjelman tai CGI-skriptin. Tästä voi myös muodostua tietoturvariski, mikäli CGI-ohjelma toimii tai se saadaan toimimaan väärällä tavalla hakien palvelimelta esimerkiksi sellaista tietoa, joka ei ole julkista. Yleensä yliopistot ja korkeakoulut ovat estäneet opiskelijoilta omien CGI-ohjelmien teon muunmuassa sen takia, koska ne kuormittavat konetta, josta ne ajetaan. Estäminen tapahtuu yleensä siten, että ylläpito kontrolloi /cgi-bin hakemistoa ja ei anna oikeuksia ajaa siellä olevia ohjelmia. Tästä voi olla ilmoituksena esimerkiksi "You don't have permission to access /~mkolsi/cgi-bin/xxxx.cgi on this server". CGI-ohjelmien sijoituspaikka on siis /cgi-bin hakemisto. [1]

Esimerkiksi www.hut.fi:n ei saa tehtyä omia CGI-sovelluksia, joskin ylläpidon puolesta on valmiina joitakin CGI-sovelluksia kuten mailto ja finger. Laskuri ohjelmaa ei ole asennettu. [2] Kyläverkossa (Trinet) olevalle omalle koneelle kuitenkin CGI-sovellusten tekeminen on mahdollista.

5 Turvallisten CGI skriptien kirjoittaminen

Viattomaltakin näyttävä CGI skripti voi aiheuttaa suurta tuhoa systeemillesi, mikäli ei pidä mielessä seuraavia asioita skriptejä kirjoittaessa:

eval -komentoa tulee välttää
asiakkaan (clientin) ei kannata antaa tehdä mitä tahansa
tulee olla varovainen popen() ja system() funktioiden käytössä
server-side included tulee ottaa pois päältä, koska niitä voi skriptit väärinkäyttää [1]

6 CGI:n spesifikaatio lyhyesti

Palvelin ja CGI skripti kommunikoivat neljällä eri tavalla, jotka ovat

Ympäristömuuttujia sekä komentoriviargumentteja käytetään datan välittämiseen informaatiopyynnöstä palvelimelta skriptille. Ympäristömuuttujat asetetaan, kun palvelin suorittaa CGI-ohjelman. Osa ympäristömuuttujista on pyyntökohtaisia ja CGI-ohjelma asettaa ne, kun taas osa ymppäristömuuttujista asetetaan aina. Esimerkkejä ympäristömuuttujista on mm. SERVER_SOFTWARE, SERVER_NAME, GATEWAY_INTERFACE, SERVER_PROTOCOL, SERVER_PORT, SEQUEST_METHOD, PATH_INFO, PATH_TRANSLATED, SCRIPT_NAME, QUERY_STRING jne. [1]

Komentoriviä käytetään vain mikäli kyseessä on ISINDEX kysely. Sitä ei siis käytetä, mikäli kyseessä on HTML lomake tai mikä muu tahansa vielä toistaiseksi määrittelemätön kyselyn tyyppi. [1]

Sellaisille pyynnöille, joiden informaatio sijaitsee otsikon jälkeen, informaatio lähetetään skriptille STDIN:iin. Tällaisia pyyntöjä ovat HTTP POST tai PUT.

Skripti lähettää tulosteetnsa stdout:iin. Tämä tulost voi olla joko dokumentti, jonka skripti on tehnyt tai komentoja palvelimelle tietyn tulosteen noutamiseksi. [1]

7 HTML-lomakkeiden dekoodaus CGI:llä

On kaksi tapaa päästä käsiksi HTML-lomakkeisiin: GET ja POST. Riippuen siitä, kumpaa näistä käyttää, saa koodatun viestin eri muodossa.

GET-metodi:

Mikäli lomakkeellasi lukee METHOD="GET", CGI ohjelmasi saa koodatun lomakkeen syötteen ympäristömuuttujassa nimeltään QUERY_STRING

POST-metodi

Mikäli lomakkeellasi on METHOD="POST", CGI ohjelmasi saa koodatun lomakkeen syötteen stdin:ssä. Palvelin ei lähdetä EOF:a datan loppumisen jälkeen, vaan sen sijaan pitää käyttää ympäristömuuttuja CONTENT_LENGTH:iä määräämään kuinka paljon dataa pitää lukea stdin:stä.

Lomaketta kirjoitettaessa jokaisella syötteellä on NAME tagi. Kun käyttäjä laittaa tietoa näihin kohtiin lomaketta, informaatio koodataan lomakkeen dataksi. Käyttäjä antaa jokaisen syötteen arvon, jota kutsutaan "arvoksi". Lomakkeen data on streami nimi=arvo pareja, jotka on erotettu &-merkillä. Jokainen nimi=arvo pari on URL koodattu l. whitespacet on muutettu plus-merkeiksi ja jotkut merkit on koodattu heksadesimaaleiksi.

8 CGI-ohjelman toimiminen käytännössä

Asiakkaan hakiessa URLia, jossa CGI-ohjelma on, palvelin ajaa ohjelman reaaliaikaisesti. Ohjelman tulostus menee asiakkaalle. CGI käyttää ympäristömuuttujia parametrien välitykseen ohjelmalle. Kaksi tähän tarkoitukseen käytettävää tärkeintä ympäristömuutujaa ovat QUERY_STRING sekä PATH_INFO. QUERY_STRING:llä tarkoitetaan mitä tahansa, joka seuraa ensimmäistä kysymysmerkkiä ("?") URL:ssa. Tämä informaatio voidaan lisätä joko ISINDEX-dokumentista tai HTML-formista GET-funktiolla. QUERY_STRING voidaan myös manuaalisesti sulauttaa HTML:ään, joka viittaa porttiin. QUERY_STRING on yleensä informaatiotiedustelu, kuten esimerkiksi, mitä käyttäjä haluaa etsiä tietokannasta. PATH_INFOa puolestaan voidaan käyttää jonkun dokumentin etsimiseen. CGI sallii lisäinformaation upottamisen URL:ii porttia varten, jota käytetään informaation välittämiseen skripteille. Tätä informaatiota ei palvelin koodaa millään tavalla. Esimerkki PATH_INFOn käytöstä on tiedostojen sijainnin siirtäminen CGI ohjelmalle. PATH_INFO:n avulla CGI-ohjelma saa tiedon, missä jokin dokumentti sijaitsee suhteessa DocumentRoot:iin. CGI ohjelmat voivat palauttaa lukuisia dokumentintyyppejä palvelimelle. Tälläisiä tyyppejä ovat mm. kuva, HTML-dokumentti, tekstidokumentti, audio-pätkä tai viittaus muihin dokumentteihin. Asiakkaan tulee tietää, mitä dokumenttityyppiä sille lähetetään, jotta dokumentti voidaan käsitellä oikein. CGI ohjelman täytyy siis kertoa palvelimelle, minkätyyppistä dokumenttia se palauttaa. Tämä kertominen tapahtuu tulosteen ns. headerissa, joka on ASCII tekstiä ja koostuu riveistä, jotka on erotettu toisistaan. [1]

Mikäli esimerkiksi palautetaan HTML:ää asiakkaalle (client), tulosteessa tulee lukea:

Content-type: text/html



        <HTML><HEAD>
        <TITLE>output of HTML from CGI script</TITLE>
        </HEAD><BODY>
        <H1>Sample output</H1>
        palautetaan <STRONG>HTML:aa</STRONG>
        </BODY></HTML>


Mikäli taas kyseessä on viite toiseen dokumenttiin, esimerkiksi WWW palvelimelta ja URL on tiedossa:

Content-type: text/html
Location: http://god.rules.org/0


   <HTML><HEAD>
   <TITLE>sori, muuttanut...</TITLE>
   </HEAD><BODY>
   <H1>....</H1>
   ...
   <A HREF="www://god.rules.org/0">a new location</A>
   on our server.
   </BODY></HTML>

Yleisesti ei ole mitään rajoitteita siitä, mitä CGI ohjelma voi hakea palvelinkoneelta verkkoon. CGI ohjelman on syytä olla kuitenkin nopeasti toimiva, jotta käyttäjä ei turhaan odottele WWW-sivulla hakua luullen, että mitään ei koskaan tapahdukaan.

9 Yhteenveto

CGI antaa omaa palvelinta pitävälle henkilölle mahdollisuuden vuorovaikutteisten ohjelmienlaittamiselle verkkoon kaikkien hyödynnettäviksi. Lukuisat tavalliset verkkosovellukset, kuten Iltalehti ONLINE, korkeakoulujen lukujärjestystietokantaohjelmat ja monet muut verkkokyselyt ja tiedonpitosovellukset hyödyntävät CGI:tä. CGI ohjelmia tehdessä tulee huomioida ohjelman hyödyllisyys ja nopeus sekä mahdolliset tietoturvariskit, kuten ns. takaovet, jolla ohjelman käyttäjä pystyisi vahingoittamaan CGI-palvelinkonetta tai lukemaan sellaista tietoa, jota hänen ei tulisi saada käsiinsä.

10 Lähdeluettelo

[1] [Anon], CGI documentations and examples. [viitattu 22.11.1998] http://hoohoo.ncsa.uiuc.edu/cgi/

[2] [Anon], Teknillinen korkeakoulu, CGI Teknillisessä korkeakoulussa [viitattu 22.11.1998] http://www.hut.fi/WWW/Tools/cgi.html

[3] [Korpela, Jukka]. PERL page. Perl is currently the most used CGI programming language. [viitattu 22.11.1998] http://www.hut.fi/~jkorpela/perl/intro.html

11 Lisätietoja

[Anon], ABC tutorial on CGI and WWW programming.
< http://www.calweb.com/~frank>
[Aldham, Danny]: Perl CGI-bin tutorial page
< http://www.postino.com/aldham/cgi.html>
[Anon], Appletscript CGI examples.
< http://edb518ea.edb.utexas.edu/scripts/cgix/cgix.html>
[Anon], CGI and WWW construction. Visual CGI.
< http://WWW.Stars.com/Vlib/Providers/CGI.html>
[Anon], CGI FAQ Wizard.
< http://starship.skyport.net/crew/davem/cgifaq/faqw.cgi>
[Anon], CGI library. Introductions how to program CGI. Perl scripts.
< http://lightsphere.com/cgi/>
[Anon], CGI resource index. (Jobs specific to CGI are posted there.)
< http://www.cgi-resources.com/>
[Anon], CGI RFC project page.
< http://Web.Golux.Com/coar/cgi/>
[Anon], FastCGI homepage.
< http://www.fastcgi.com>
[Anon], Information about processing of CGI GET script arguments under Tcl.
< http://www-itg.lbl.gov/~clarsen/projects/htcl/http-proc-args.html>
[Niskanen, Pekka]. LuK-tutkielma: CGI-rajapinta ja internet
< http://www.cs.uku.fi/~jniskane/luk/index.htm>
[Anon], Remotely hosted CGI scripts.
< http://www.cgiforme.com>
[Anon], The Amiga HTTP Common Gateway Interface.
< http://www.phone.net/amiga-docs/>
[Anon], Using the Java CGI classes.
< http://garbo.uwasa.fi/ldp/HOWTO/Java-CGI-HOWTO-5.html>
[Anon],W3C CGI page.
< http://www.w3.org/CGI/>
[Anon], W3C httpd CGI/1.1 Script Support
< http://www.w3.org/Daemon/User/CGI/Overview.html>
[Anon], WWWboard. Perl based bulletin board system (BBS).
< http://www.worldwidemart.com/scripts/wwwboard.shtml>