2004-07-07

Käsittele URL oikein (opas HTTP-palvelinten kehittäjille)

Vaikka olenkin lukemassa Cooperin kiinnostavaa kirjaa teknisistä vimpaimista ja se on jo puolivälin kohdalla herättänyt vuorovaikutukseen liittyviä ajatuksenpoikasia, taidan täällä kuitenkaan jatkaa teknisellä linjalla. Tässä on dokumenttien RFC 2616 ja RFC 2396 perusteella kokoamani resepti oikeaoppiseen ja turvalliseen URL:ien käsittelyyn. Aasinsilta käytettävyyteen löytyy kyllä siitä, että huonosti toteutettu URL:ien käsittely estää tiettyjen merkkien syöttämisen palvelimelle, mutta siitäkin huolimatta tämä juttu kiinnostanee lähinnä ohjelmoijia.

1. Muista että Request-Line eli kyselyn ensimmäinen rivi saattaa sisältää Request-URI:na myös kokonaisen, eli protokollan, palvelinosan ja portin sisältävän URL:in. Mikäli Request-URI ei ala /-merkillä, tulee löydetyn palvelimen ohittaa Host-otsake. Esimerkki:

GET /index.html HTTP/1.1
Host: www.example.com


GET http://www.example.com/index.html HTTP/1.1
Host: www.example.net


Kumpikin näistä viittaavat tiedostoon index.html palvelimen www.example.com dokumenttijuuressa.

2. Pura URL osiin ennen koodauksen poistamista. Toisin sanoen, etsi aluksi kysymysmerkkiä:

abs_path ? query

3. Mikäli query löytyi, erottele parametrit toisistaan et-merkkien kohdilta:

param1 & param2 & param3

Seuraavaksi erota jokaisesta parametrista nimi ja arvo:

name = value

Nyt voit dekoodata namen ja valuen. Ja kuten huomaat, name-value -parin osat tulee dekoodata erillään toisistaan. Mikäli et salli jotain tiettyjä merkkejä nimissä ja arvoissa, kerro siitä 403 Forbidden -viestillä.

4. Pilko nyt abs_path kauttaviivojen kohdilta:

/ segment1 / segment2 / segment3

Dekoodaa sen jälkeen jokainen segmentti erikseen. Ja taas, mikäli et salli jotain merkkejä, ilmoita siitä mieluiten 403:lla. Myös puolipisteellä on erityismerkitys, tutustu RFC-dokumenttiin mikäli tarvitset tarkempia tietoja.

Mitä tästä nyt sitten kannattaa huomata on että URL:in osat dekoodataan vasta aivan lopuksi. Se että osa abs_path dekoodataan liian aikaisessa vaiheessa ei aiheuta paljoa ongelmia, sillä / on harvemmin sallittu hakemistojen tai tiedostojen nimissä. Sen sijaan liian aikanen query-osan dekoodaminen johtaa ongelmiin varsinkin et-merkkien käsittelyssä. Yleinen harhaluulo on että aikainen dekoodaaminen on hyväksi turvallisuudelle ja siksi kannattaa mennä siitä missä aita on matalin. Turvallisuudesta joutuu kuitenkin lopulta huolehtimaan yksittäisten osasten tasolla, joten oikeaoppinen käsittely ei sittenkään aiheuta niin kovin paljoa lisävaivaa.