Turvallisempien palvelujen toteuttaminen
Mureakuha
Sisällysluettelo |
Alkusanat
Vaikkakin oleellinen osa verkkopalvelun turvallisuutta on sen alla pyörivän järjestelmän (www-palvelin, käyttöjärjestelmä, käyttäjäoikeudet, palomuurit yms) turvallisuus, niin jätän ne tylysti huomiotta ja keskityn täysin pelkän palvelun turvallisuuden takaamiseen, tai ainakin parantamiseen. Koska täysin turvallista verkossa olevaa palvelua ei voi olla olemassa, olisi hyvä pitää esittämiäni huomioita korkeintaan neuvoa antavina, eikä missään nimessä ajatella, että niiden täyttäminen missään nimessä takaisi palvelun turvallisuuden.
Yleisnäkymä
Palvelun kriittiset kohdat koostuvat palvelusta itsestään, sen käyttäjistä sekä verkosta näiden välillä. Mikään näistä kolmesta tekijästä ei saa luottaa toisiinsa.
Käyttäjä - palvelu
Käyttäjien näkökulmasta verkossa liikkuva data on turvatonta. Myöskään palveluun itseensä ei voi luottaa. 'traceroute mureakuha.com' (tai tracert mureakuha.com windowsissa) kertoo itsesi ja tämän palvelimen välillä olevat koneet. Millä tahansa näistä koneista voi olla palvelu, joka loggaa liikennettä, johon tallentuu kaikki liikenne itsesi ja mureakuha.com:n välillä. Tätä varten on kehitetty erinäisiä salausmetodeja, jotka muuttavat datan vaikeasti luettavaan muotoon. Data pystytään kuitenkin tallentamaan ja brute forcettamaan auki jossain ajassa, joten ei voi olettaa, että nyt turvalliselta tuntuva maksutapahtuma Nordean konttoriin ei selviäisi myöhemmin. Tämän takia pankkipalveluissa käytetäänkin SSL-salauksen lisäksi vaihtuvia tunnusnumeroita, jotta puretulla tiedolla ei kuitenkaan pystyisi suorittamaan rahasiirtoja.
Mutta voitko olla varma, että olet yhteydessä Nordeaan? Muuttamalla nordea.fi:n IP-osoitteen tietyllä tavalla modifioiduksi proxy-palvelimeksi DNS:ssä muodostatkin salatun yhteyden proxyyn, joka puolestaan muodostaa oman yhteytensä Nordean palveluun. Tästä tosin kertoo SSL-sertifikaatti, joka pompahtaa esiin yhteyttä muodostettaessa, mutta tämän tiedon käyttäjä jättää helposti huomiotta. Näin maksaessasi Aku Ankan tilausta Sanoma Magasines Finlandille proxy muuttaakin tilinumeroa ja summaa itsestään eteenpäin ja yhtäkkiä tilisi sisältö onkin ilkeämielisen kräkkerin tilillä.
Palvelu - käyttäjä
Palvelun tulisi suhtautua kaikkiin käyttäjiinsä vähintäänkin epäilevästi, ellei suorastaan paranoidisti. Luotetun käyttäjän salasana on voitu kräkätä ja näin käyttäjä ei olekaan se, joksi palvelu sitä luulee. Myös luotetut käyttäjät voivat harrastaa vandalismia syystä tai toisesta. Yksi ylläpitäjistä suuttuu johtoportaaseen ja poistaa kaikki tiedot kannasta, tai julkaisee perusteettomia väitteitä. Esimerkiksi pörssiosakeyhtiön osavuosikatsauksen näpertely juuri sopivalla tavalla voi tuottaa merkittävän rahallisen menetyksen.
Tahallisen vandalismin lisäksi pitää ottaa huomioon vahingot. Kuinka helppoa käyttäjän on tuhota tietoa vahingossa?
Lyhyt yhteenveto
Käyttäjän tulisi olla tarpeeksi vakuuttunut siitä, että on todellakin yhteydessä tavoittelemaansa palveluun, sekä tiedonvälitys käyttäjän ja palvelun välillä on tarpeeksi turvallista.
Palvelun on, käyttäjän autentikoimisen jälkeen, pystyttävä varmistamaan, että käyttäjä ei pääse tekemään peruuttamatonta vahinkoa palvelulle.
Autentikointi
Käyttäjän tullessa palveluun hänen täytyy jollain todistaa palvelulle henkilöllisyytensä. Yleensä tämä tehdään syöttämällä käyttäjätunnus ja salasana. Hyvä autentikaatio perustuu ainakin kahteen kolmesta tavasta autentikoitua.
Fyysinen tunnistus
Verkkokalvon skannaus, sormenjälki, tai tavallisimmillaan pikapankkikortti. Jokin fyysinen yksilöllinen kappale. Koska tämän vieminen käyttäjältä vaatii fyysistä kontaktia ainakin itse esineeseen, on melko epätodennäköistä, että joku meksikolainen kräkkeri tulee Suomeen asti viemään juuri sinun pankkikorttisi. Kuitenkaan pelkällä kortilla ei juuri juhlita, koska se voidaan hukata, joku voi varastaa sen ja siitä voidaan tehdä kopio.
Tunnussana, -koodi
Salasana, jonka vain käyttäjä tuntee, vaatii visuaalisen tai muun keinon saada se haltuunsa. Oli se sitten joku kurkkimassa olkasi yli kun naputtelet PIN-koodiasi kännykkääsi tai Kalle Kräkkeri ISP:si linjoilla kuuntelemassa verkkoyhteyttäsi, vaaditaan ainakin jonkinlainen tapa saada tämä tieto haltuun. PIN-koodit ovat kuitenkin yleensä heikkoja (esimerkiksi pankkikortin neljä numeroa) ja useat monimutkaiset salasanat tuppaavat unohtumaan, mikäli niitä ei käytetä tarpeeksi, joten pelkältään tämäkään tapa todistaa henkilöllisyytensä ei ole riittävä.
Vuorovaikutteinen autentikaatio
Tällä tarkoitan, että palvelu kysyy jotain tiettyä vaihtuvaa seikkaa käyttäjältä, joka vaihtelee käyttökerroittain. On se sitten vaihtuva salasana, jokin tietty käyttäjän ominaisuus tai muu vastaava vaikeasti selville otettava käyttäjälle henkilökohtainen tieto. Esimerkiksi Nordea käyttää tätä sisäänloggautumisessa (vaihtuva numerosarja) sekä laskunmaksun vahvistuksessa (jokin monesta uudelleen käytettävistä ennaltamäärätyistä numerosarjoista).
2.2 Kaikilla näillä menetelmillä on omat heikkoutensa ja vahvat puolensa, mutta nekään eivät ole toisiaan pois sulkevia. Kuitenkin kaikkien näiden menetelmien heikoin lenkki on käyttäjä itse: yksinkertaiset salasanat, helposti hankittavissa oleva pankkikortti, käyttäjän tietoihin perehtyminen tai niiden varastaminen. Koska palvelun ylläpitohenkilöstö ei kuitenkaan voi käydä tarkastamassa paikan päällä, että käyttäjä oikeasti on se, kuka väittää olevansa, on jossain määrin pakko luottaa käyttäjän sanaan. Ei kuitenkaan sokeasti.
2.3 Käyttäjästä tulee kirjata kirjautumisvaiheessa, autentikoinnin jälkeen, mahdollisimman paljon tietoja. Mikäli nämä ei-kriittiset tiedot ovat vaihtuneet tarpeeksi, voi olla syytä toimenpiteisiin. Esimerkiksi Matti Meikäläinen käyttää yleensä IE:tä ja on Soneran Helsingissä sijaitsevasta ADSL-liittymästä. Mikäli Matti tuleekin järjestelmään Operalla Kolumbuksen liittymästä, voi jotain olla vialla. Koska Matti voi kuitenkin olla kirjastossa tai kaverillaan, ei häntä kuitenkaan voida tästä hylätä, mutta lokitiedostoon kannattaa ehkä tehdä tästä erikoismerkintä.
2.4 Koska HTTP on luonteeltaan katkonaista (jokainen sivunlataus on uusi yhteys, joka sivunlatauksen jälkeen katkaistaan) on oltava jonkinlainen tapa tietää, että sivua lataamaan alkava käyttäjä on Matti Meikäläinen, ilman että hän autentikoituu jokaista valitsemaansa sivua varten. Yleisimmin tämä hoidetaan sessioilla. Käyttäjän autentikoiduttua hänelle annetaan sessiotunniste (sessioid), jolla ko. käyttäjä seuraavilla sivuilla tunnistetaan.
2.4.1 Koska käyttäjän voidaan olettaa selaavan useita sivuja, tulee sessioid:n olla vaikeasti arvattava. Tämä sen takia, että kuka tahansa kyseisellä sessioid:llä tunnistetaan Matti Meikäläiseksi. Sessiotunnisteessa on hyvä olla tarpeeksi vaihtoehtoja (esimerkiksi jos sessioid koostuu neljästä numerosta, on mahdollinen numeroavaruus käyty läpi (riippuen yhteyden laadusta) muutamissa sekunneissa.) Mikäli sessioid koostuu vaikkapa 32 merkistä numeroja, isoja ja pieniä kirjaimia, on vaihtoehtoja jo niin paljon, että oikean sessioid:n löytämiseen menee parhaimmillaankin vuosia. Todennäköisempää on, että palvelinjärjestelmä ylikuormittuu, kuin että oikea sessioid löytyy. Tarpeeksi monimutkaisen sessioid:n lisäksi käyttäjän on mahdotonta vaihtaa selainta session aikana, joten sitä voidaan myös käyttää sessioid:n lisäksi. Toisaalta käyttäjä saattaa pystyä vaihtamaan sitä selainnimeä, jonka selain lähettää pyynnön yhteydessä, mutta tätä toisaalta ei voi tehdä vahingossa ja se siten voitanee pitää käyttäjän "omana mokana". Jotkut ISP:t vaihtelevat proxya sivunlatausten välillä, joten käyttäjän IP saattaa muuttua, mutta mikäli tietyt muutokset sallitaan (Soneran käyttämien proxyjen IP-avaruus tai domainin pääte tuskin vaihtuvat Kolumbuksen vastaaviksi) niin tämäkin on mahdollista käyttää hyväksi. Sessioid:tä ei kuitenkaan voi vaihtaa joka latauskerta, koska tämä estäisi Takaisin-napin käytön. Lisäksi sessioiden pitäisi vanhentua. Mikäli käyttäjä on tietyn ajan lataamatta uutta sivua, tulee hänen autentikoitua uudelleen. Tämän ajastuksen tulee olla palvelinpäässä, koska käyttäjän cookieiden vanhentumiseen ei voi luottaa.
2.5 Salasanoja tulee säilyttää palvelussa salattuina tai verrannaistietona. Esimerkiksi MD5-hash ei sisällä salasanaa, vaan sarjan numeroita ja kirjaimia jotka muodostuvat salasanasta ja mahdollisesta lisäyksestä salasanaan.
Käyttäjän toimenpiteet
Tietojen poisto
Koska käyttäjään ei autentikoitumisen jälkeenkään voi luottaa ja käyttäjä voi tehdä virheitä, tulee näiden määrä minimoida. Mikäli mahdollista tilan suhteen, mitään tietoa ei tule poistaa järjestelmästä kokonaan, ainoastaan merkitä poistetuksi. (Vrt. et poista tiedostoa, vaan se siirtyy Roskakoriin.) Näin tiedon palautus on nopeaa ja helppoa tarpeen vaatiessa. Kun tieto on ollut karenssiajan poistettuna, voi se siirtyä ylläpidon tietoon, joka hoitaa sen poistamisen järjestelmästä. Kaiken tiedon tulee kuitenkin säilyä viimeistään backupeilla.
Toimintojen vaiheistus
Mikään tapahtuma, joka voidaan joutua peruuttamaan (kuten tietojen poistaminen/muutos) ei saa olla yhden vaiheen takana. Mikäli sivuilla on linkki joka johtaa tiedon poistamiseen, tulee olla välivaihe, joka varmistaa, että käyttäjä varmasti haluaa poistaa tiedon. Mikäli tietoa muutetaan, on hyvä säilyttää aikaisemmista versioista tiedot jossain, jotta muutettu tieto saadaan palautettua.
Tiedon varmentaminen
Käyttäjän syöte pitää tarkastaa ja virheellisestä tiedosta ilmoittaa. Jos käyttäjältä pyydetään puhelinnumeroa, ei siinä sallita kirjaimia. Koska sallimattoman tiedon määrittely on vaikeaa, on helpompi määritellä, mitä sallitaan. Puhelinnumero voi siis koostua numeroista, välilyönneistä, + ja - -merkeistä ja suluista. (Esim +358-(0)9-123 4567.) Miten tämä sitten tallennetaan, on asia erikseen. Hyvä järjestelmä kuitenkin sallii datan antamisen monessa muodossa. Monet paljonkin käytetyt järjestelmät sisältävät toinen toistaan tyhmempiä virheitä, jotka sallivat SQL-injektion eli tietokanta-kyselyiden muuttamisen. Mikäli käyttäjältä esimerkiksi pyydetään etunimeä ja sitä käytetään suoraan kyselyssä "INSERT INTO user (firstname) VALUES ('$firstname') WHERE username='mattim';" tapahtuu kivaa, kun etunimi-kenttään kirjotetaankin "'); DELETE FROM user;"
Kaikki käyttäjän antama data nimistä puhelinnumeroihin, lähetettyihin tiedostoihin ja polkuihin tulee varmentaa kunnollisiksi. Esimerkiksi jos käyttäjän keskustelupalsta-ikoniksi lähettämää kuvaa ei tarkasteta että se todellakin on kuva, voi se olla IE:n viimeisintä reikää käyttävä JavaScripti, joka formatoi käyttäjän kiintolevyn. Hyvä kooderi katsoo kumpaankin suuntaan ylittäessään yksisuuntaista tietä.
Virheviestit
Virheviestit on tarkoitettu ylläpitoa varten. Ei käyttäjiä. Käyttäjät eivät raportoi virheistä ylläpidolle, palvelun tulee tehdä se. "SQL ERROR near line 1: INSERT blaa blaa" ei saa missään tapauksessa päästä käyttäjän silmille. Sen sijaan scripti, joka lähettää ylläpidolle mahdollisimman paljon tietoa käyttäjän toimista ennen virhettä sekä käyttäjälle tulostettu virhe "Tietokantavirhe. Ylläpidolle on ilmoitettu." ei kerro paljon enempää tai vähempää käyttäjälle, mutta hankaloittaa käyttäjää itseään hyväksikäyttämästä ohjelmointivirhettä. Mikäli joku käyttäjä aiheuttaa tarpeeksi virheitä, voi olla hyvä logata käyttäjä pois tai lukita kyseinen tunnus toistaiseksi. Mikäli virheet koituivat kuitenkin ohjelmointivirheestä eivätkä käyttäjästä, käyttäjän tunnuksen sulkeminen ei ole kauhean ystävällinen temppu. Kannattaa harkita automatisoituja toimenpiteitä, mitkä ovat haitat ja mitkä hyödyt.
Käyttäjähierarkia
Yhteenkään käyttäjään ei ole luottamista. Tämän takia kriittisten toimenpiteitten suorittamiseen kannattaa vaatia toisen tai useamman käyttäjän suostumus. Jos Janne Julkaisumies päättää julkaista uuden uutisen, voi se vaatia vaikkapa Tero Tutkijan hyväksymisen ennen kuin se päästetään ulos ihmisten ilmoille. Mikäli taas Tero tekee muutoksia Jannen uutiseen, tulee Jannen tai jonkun muun hyväksyä se. Kaikista muutoksista ja hyväksymisistä kannattaa pitää kirjaa, jotta väärinkäytösten yhteydessä syyllinen löydetään. Tälläisellä sisällön auditoimisella myös vältetään virheet sisällössä.
Monimutkaisuuden tuoma turvallisuus
Tämä tunnetaan paremmin lauseella 'security through obscurity'. Esimerkiksi oletetaan, että ylläpitopuoli on piilossa, kun siihen ei ole linkkiä missään. Tähän syyllistyvät isotkin yritykset. Muun turvallisuuden lisäksi ja oikein ymmärrettynä tämä kuitenkin voi parantaa turvallisuutta. Esimerkiksi mikäli ylläpitosivuston oikeudet, autentikaatio yms on kunnossa, niin ei siitä ainakaan haittaa ole, että ylläpitosivut sijaitsevat http://www.yritys.fi/admin/ -osoitteen sijaan vaikkapa http://admin.yritys.fi/hallinta/ -osoitteessa, jonne ei ole linkkiä missään. Korostan kuitenkin, että tämä on lähinnä pinnallinen turva. Ei pidä siis hetkeäkään luottaa siihen, että ilkeämielinen käyttäjä ei löytäisi osoitetta.
Loppusanat
Monet ylläkäydyt toimenpiteet palvelun turvaamiseksi eivät ole tarpeen kaikissa palveluissa. Siinä, missä itse en todellakaan jaksaisi nähdä noin paljon vaivaa omien kotisivujeni päivityksen turvaamiseen, en usko että edellämainitut toimenpiteet riittäisivät esimerkiksi webissä toimivan pankin turvaamiseksi (vaikka jotkin pankit suomessa käyttävät heikompaakin tapaa turvata tilipalvelunsa, kuin kuvailemani). Toisaalta, ei liiasta turvallisuudesta haittaakaan ole. Kannattaa kuitenkin muistaa seuraavat seikat:
- Käyttäjä on tyhmä
- Palvelua ei käytetä suunnitellulla tavalla
- Täydellistä tietoturvaa ei ole (ei vaikka tietokone olisi sammuksissa - se voidaan varastaa)
