Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Turvallinen tunnistautuminen evästeellä

Sivun loppuun

seppe [10.08.2010 20:29:46]

#

Minulla on pieni nettisivu projekti ja olen olen suunnittelemassa siihen tunnistautumisjärjestelmää. Minulla ei ole aikaisempaa kokemusta tämänkaltaisen järjestelmän toteuttamisesta, joten arvostaisin palautetta.

Sisäänkirjautumisen jälkeen käyttäjä tunnistettaisiin evästeestä, jonka sisällön rakenne olisi seuraava:

[käyttäjä id].[istunnon vanhentumisaika].[ sha1 hash ( suola + käyttäjä id + vanhenemisaika + browser headers + IP osoite ) ]

Piste on erottimena kyseisessä merkkijonossa.

Tarkoituksena on tarkistaa evästeellä että evästettä ei ole muutettu ja että se on voimassa.

Onko jotain mitä kannattaisi lisätä tai muuttaa?

Triton [10.08.2010 20:36:57]

#

Riippuu nyt tietenkin vähän siitä, että mitä kieltä olet käyttämässä, mutta jos PHP on kielenä, niin käytä evästeiden sijasta mielummin istuntoja (sessions). Kaikki olennainen tieto, jota tällaisen homman tekemiseen tarvitaan löytyy todella hyvin täältä http://wiki.mureakuha.com/wiki/Turvallisten_www-sovellusten_koodaus_php:llä .

Edit. Kuten tulet huomaamaan, kun luet tuota mureakuhan juttua, niin tuon istuntotunnisteen varmistaminen onnistuu helpoiten siten, että luot funktion, joka generoi aina saman istuntotunnisteen (siis tietenkin kone kohtaisesti) ja tätä vertaat, sitten sen istuntoon tallennetun kanssa.

Edit2. Itse olen joskus tehnyt myös niin, että olen tallentanut istuntotunnisteen istunnon lisäksi myös tietokantaan käyttäjätietojen kanssa ja verran niitä keskenään. Tällöin voit luoda aina täysin satunnaisen istuntotunnisteen. Huononapuolena tai etuna (miten sen nyt ottaa) tuo estää sen, että käyttäjä ei voi olla yhtäaikaa kirjautuneena useammalta koneelta...

seppe [10.08.2010 20:42:57]

#

PHPn istunnoissa ei ymmärtääkseni kovinkaan helppoa asettaa istuntokohtaista voimassaoloaikaa ja muistaakseni istunnot myös katkeavat kun selain suljetaan.

Evästeissä voi asettaa voimassaoloajan ja kun se myös laitetaan tohon hashiin, niin tunnistautuminen voidaan myös todeta vanhentuneeksi vaikka selain ei olisi sitä poistanut.

Kaikki käyttäjäkohtainen tieto haetaan tietokannasta sen jälkeen kun evästee on todettu kelvolliseksi.

@Edit: Tuo hash on evästeessä juuri sitä varten että voidaan varmistaa, että IP ja selain ovat samoja kun kirjauduttaessa.

Triton [10.08.2010 20:48:50]

#

Tietoturvan taso tulee taas laskemaan aika merkittävästi. Istunto tiedot tallennetaan serverille, mutta evästeet käyttäjän koneelle. Näin ollen kolmasosapuoli voi penkoa evästeet esiin ja käyttää niitä. Voithan tehdä myös oman istuntojärjestelmän, joka tallentaan kaikki tiedot tietokantaan. Näin voit myös luoda ominaisuuden, joka mahdollistaa yksittäisten istuntojen vanhentumisajan määrittämisen. PHP:ssä pystyy kyllä uudelleenasettaa tuon PHPSESSID-evästeen vanhentumisajan.

Edit. IP:n käyttäminen ei välttämättä ole kovin hyvä ajatus, sillä joillakin käyttäjillä IP voi vaihtua säännöllisin väliajoin. Tietenkin jos tämä on henkilökohtainen hallintapaneeli, niin sitten sillä ei ole väliä.

Edit2. Muista myös, että evästeen muuttaminen on kolmannenosapuolen ohjelmilla mahdollista, jolloin hakkeri voi muuttaa evästettä oman koneen tietojen mukaisesti....

seppe [10.08.2010 20:52:32]

#

Perehdyitkö ollenkaan tuohon evästeeseen?

Ideana on että mikään muu tieto käyttäjästä IDtä lukkuunottamatta ei tallennu evästeeseen. Sitten kun eväste on tarkistettu kyseisen tarkistussumman avulla ja todettu kelvolliseksi, tarvittavat tiedot haetaan esim. tietokannasta, eikä niitä koskaan tarvitse tallentaa mihinkään evästeeseen.

@Edit, se on hyvin helposti muutettavissa jos tarve vaatii, IP on siellä sitä varten, että on yksi tapa lisää yrittää varmentaa evästeen kelvollisuus

@Edit2, Kerro toki, jos tiedät miten muokkaat kyseistä evästettä niin että sen sisältö muuttuu (käyttäjä id tai vanhentumisaika) ja se silti läpäisee tarkistuksen joka tehdään laskemalla tuo hash uudelleen evästeen tiedoista ja vertaamalla sitä evästeen sisältämään hashiin.

Triton [10.08.2010 21:01:46]

#

Käyttäjä-id:n sekä vanhentumisjan pystyy erittäin helposti bruteforcettamaan... Jokatapauksessa jää jäljelle vielä CSRF-aukko, jolta tämä homma ei suojaa millään tavalla. Siksi tutustuisin antamaani sivuun. Ja kyllä perehdyin evästeeseen.

seppe [10.08.2010 21:11:49]

#

Voisitko antaa esimerkin tuosta vanhentumisajan ja käyttäjä id:n bruteforcettamisesta?

Uniikin tunnisteen CSRF hyökkäyksiä vastaan voi tallentaa taas sinne tietokantaan (joka pysyy aina siellä palvelimen puolella) ja sitten kaikki toiminnot olisivat tyyliin logout?csrf_token=uniikki_tunniste (kuten mureakuhan esimerkissä).

Triton [10.08.2010 21:18:19]

#

Tiedätkö mitä bruteforce-menetelmä tarkoittaa? Jos tiedät, niin siinä generoidaan järjestyksessä kaikki mahdolliset vaihtoehdot läpi kunnes saadaan onnistunut ratkaisu. Eli generoidaan nuo yksilölliset tiedot ja yhdistetään ne tuohon kaavaasi ja sitten verrataan tietokantaan sekä koneentietoihin. Itse tein jokunen vuosi sitten pythonilla pelkän bruteforce-algoritmin, joka kävi muutamassa minuutissa kymmenisenmiljoonaa vaihtoehtoa läpi. Mietä mitä joku oikea krakkeri saisi aikaan?

seppe [10.08.2010 21:55:44]

#

Hash osassa on mukana myös suola. Krakkeri ei myöskään tiedä missä järjestyksessä yksilölliset osat ovat ja juuri mitkä tiedot tuossa hashissa on. Tietenkin voidaan olettaa sellainen tilanne, jossa krakkeri tietää myös mitä tietoja hashiin on laitettu ja missä järjestyksessä ne ovat, niin ymmärtääkseni silloin pelkkä suola tarvitsee murtaa.

Jos lähtökohatana on, että krakkeri tietää menetelmän miten hash on luotu, voiko siltä suojautua muutoin kuin lisäämällä hashiin joka kirjautumiskerralla muuttuvan yksilöllisen eväste/käyttäjäkohtataisen tunnisteen?

Triton [10.08.2010 22:05:47]

#

Niin no lähtökohtahan on se, että järjestelmä tunnistaa sinut nimenomaan tuon istuntotunnisteen perusteella, joten jos krakkeri tietää kaavan miten tunniste luodaan, niin se siitä suojauksesta. Tällä hetkellä ei tule muuta mieleen, kuin satunnaiset suolat. Edellä mainittu toimii ihan hyvin kun otetaan se tietokanta mukaan.

Edit. Mutta siis kun istuntoja käytetään, niin silloin evästeiden manipulointi ei onnistu.

Antti Laaksonen [10.08.2010 22:28:44]

#

PHP:n istunnon tunnus tallennetaan yleensä evästeeseen. Hyökkääjä pystyy muuttamaan evästeessä olevaa istunnon tunnusta samalla tavalla kuin kaikkia muitakin evästeitä. Toinen mahdollisuus on välittää istunnon tunnus URL:n mukana, jolloin hyökkäjä pystyy myös muuttamaan tunnusta.

PHP:n omia istuntoja ei ole mikään pakko käyttää, vaan istuntojen hallinnan voi toteuttaa myös itse. Yksi ratkaisu on arpoa kirjautumisen yhteydessä istunnon tunnus ja tallentaa se evästeeseen sekä tietokantaan käyttäjän kohdalle.

En väittäisi silti, että oma ehdotuksesikaan olisi helposti murrettavissa. Hyökkääjä voi arvata evästeen osia, mutta hyökkääjä voi myös arvata käyttäjän salasanan.

raakaliha [10.08.2010 22:29:02]

#

Käyttäjän id pitäisi säilyttää palvelimella ja niihin viitataan istuntotunnuksella joka lähetetään evästeessä. Muun tiedon voi tunkea evästeisiin sit. (selkokielisesti)

Triton [10.08.2010 22:48:48]

#

Antti Laaksonen kirjoitti:

PHP:n istunnon tunnus tallennetaan yleensä evästeeseen. Hyökkääjä pystyy muuttamaan evästeessä olevaa istunnon tunnusta samalla tavalla kuin kaikkia muitakin evästeitä.

Tietystihän se on mahdollista, mutta kuten jo keskustelun alussa seppe totesikin, niin tämä PHPSESSID-eväste vanhenee aina selaimen sulkemisen jälkeen, joten aikaa tunnisteen murtamiseen ei kovin kauaa ole (ja vaikkei selainta suljettaisikaan, niin tunniste vanhenee itsekseen muistaakseni parissa tunnissa). Jos evästeelle annetaan pitkä vanhentumisaika, niin murtautumisen mahdollisuudet kasvavat.

Antti Laaksonen kirjoitti:

En väittäisi silti, että oma (sepen) ehdotuksesikaan olisi helposti murrettavissa. Hyökkääjä voi arvata evästeen osia, mutta hyökkääjä voi myös arvata käyttäjän salasanan.

Itse ajattelen asiat aina pahimman skenaarion kautta. Kun kyseessä ei ole mikään suosittu palvelu, niin harvemmin oikeita krakkereita kiinnostaa pienten saittien murtaminen, jolloin tuon tasoinen menetelmä tod. näk. riittää. Toki on mahdollista, että salasanan voi keksiä (tai vaikka bruteforcettaa), mutta tämä voidaan estää yksikertaisesti siten, että kerätään epäonnistuneet kirjautumisyritykset lokiin ja jos samalta koneelta epäonnistutaan esim. 3-5 kertaa peräkkäin estetään kirjautuminen esim. 30 minuutin ajaksi... Näin tehdään salasanojen arvailuistakin todella hankalaa.

Tietenkin salasanoja voidaan myös kaapata oikeilta käyttäjiltä, ellei käytetä suojattuayhteyttä...

seppe [10.08.2010 23:24:01]

#

Oma ajatukseni olisi pitää istunnot ja kirjautuminen erillään. Istunnoissa oleva tieto voi tyhjentyä kun selain istunto vanhenee tai kun selain suljetaan. Kuitenkin olisi tarkoitus että kirjautuminen olisi muistissa, ettei joka kerta kun istunto vanhenee tarvitsisi kirjautua uudelleen.

Itselläni on mielessä että juuri esim. CSRF tunnisteet voisi tallentaa istuntoon ja ne muuttuisivat viimeistään kun istunto tyhjenee.

Olisiko varsin turvallinen menetelmä, jos evästeensen tallentaisi vain yksilöllisen ID:n jolla tieto haettaisiin lopulta tietokannasta missä olisi myös tallennettuna hash ( yksilöllinen ID , IP , Browser headerit , suola ) ,joka on luotu kirjautumishetkellä, jota sitten verrataan samalla menetelmällä luotuun hashiin.

Triton [11.08.2010 00:19:12]

#

seppe kirjoitti:

Olisiko varsin turvallinen menetelmä, jos evästeensen tallentaisi vain yksilöllisen ID:n jolla tieto haettaisiin lopulta tietokannasta missä olisi myös tallennettuna hash ( yksilöllinen ID , IP , Browser headerit , suola ) ,joka on luotu kirjautumishetkellä, jota sitten verrataan samalla menetelmällä luotuun hashiin.

Minusta tuo ehdotus on jo huomattavasti parempi. Tosin kannattaa miettiä tarkkaa, mitä tietoja ottaa tuohon hashiin mukaan. Esimerkiksi mitään arkaluontoisia käyttäjätietoja ei tule ottaa mukaan. IP:kin on sinällään huono, jos se vaihtuu säännöllisin aikavälein (kuten jo aikaisemmin mainitsinkin)...

Grez [11.08.2010 01:24:47]

#

Mä en nyt oikein ymmärrä mitä ideaa tuossa on edes leikkiä millään hashilla. Tehdään vaikka 200 merkkiä laadukasta satunnaisuutta ja lähetetään se käyttäjälle keksinä ja sitä vastaan löytyy sitten palvelimen päästä kuka on kyseessä ja kaikki muu istuntoon liittyvä tieto.

Ehkä joku osaa kertoa miksi tuo häshäys on hyvä idea? Mutta jos ei, niin mielestäni sitä ei ole mitään järkeä käyttää jos siitä ei ole todellista hyötyä. Ei vaikka se olisikin "hieno" tekniikka josta on jossain muussa yhteydessä hyötyä.

Törmäsin tässä juuri erään suomen top 50 yrityksen järjestelmässä todella hienoon javascriptillä tehtyy md5-toteutukseen, jonka käytöstä ei ollut yhtään mitään todellista hyötyä. Tai no oli siitä varmaan järjestelmän toteuttaneelle yritykselle se hyöty, että sai senkin tekemisestä varmaan kasaan laskutettavia tunteja.

Triton [11.08.2010 02:01:54]

#

Niin no tiivistefunktiot ovat hyödyllisiä niissä tilanteissa, kun täytyy joku merkkijono saada ei-selkokieliseksi sillä tavoin, että joka kerta kun operaatio suoritetaan, niin tulos on sama. Eli periaatteessa välttämötän salasanan suojaamista ajatellen...

Mutta sellaisessa tilanteessa, ettei samaa tiivistettä täydy saada muodostettua uudelleen, niin tuo 200 merkkiä pitkä satunnaismerkkijono on varsin hyvä idea, sillä sitä ei ihan hetkessä bruteforcetetakkaan.

seppe [11.08.2010 08:25:45]

#

Gerz: Kyllä samaa merkkijonoa voi verrata selväkielisenäkin aivan yhtä hyvin, mutta hash vie vähemmän tilaa. Jos taas keksissä on pelkkä se satunnainen merkkijono ja eikä sitä millään tavalla yhdistetä käyttäjään, niin tietämällä evästeen sisällön voi joku kaapata kirjautumisen.

Tuo suola siellä on taas sitä varten ettei pelkillä käyttäjän tiedoilla voi muodostaa tunnistetta johon verrataan, mutta toisaalta ei sen merkitys taida olla kovinkaan suuri tässä tapauksessa, vai olenko väärässä.

Grez [11.08.2010 11:16:22]

#

seppe kirjoitti:

Gerz: Kyllä samaa merkkijonoa voi verrata selväkielisenäkin aivan yhtä hyvin, mutta hash vie vähemmän tilaa. Jos taas keksissä on pelkkä se satunnainen merkkijono ja eikä sitä millään tavalla yhdistetä käyttäjään, niin tietämällä evästeen sisällön voi joku kaapata kirjautumisen.

Hashin tarkoitus on lisätä tietoturvaa poistamalla tietoa jota ei haluta säilyttää.

Tässä taas nimenomaan halutaan mahdollisimman paljon mahdollisimman epäarvattavaa tietoa, jotta tietoturva olisi mahdollismman hyvä. Toki jos päätetään että esim. 160 bittiä on riittävän paljon estämään mahdolliset törmäykset, niin sitten tehdään 160 bittiä satunnaisuutta, eikä 200 merkkiä kuten ehdotin. Tällöin vertailtavaa on ihan yhtä paljon kuin (160 bittisellä) tiivisteellä, mutta ratkaisussa ei ole muita tiivistealgoritmille tyypillisiä heikkouksia kuin törmäys.

seppe kirjoitti:

Tuo suola siellä on taas sitä varten ettei pelkillä käyttäjän tiedoilla voi muodostaa tunnistetta johon verrataan, mutta toisaalta ei sen merkitys taida olla kovinkaan suuri tässä tapauksessa, vai olenko väärässä.

Tietenkin suolan kanssa on parempi kuin ilman suolaa, mutta vielä parempi on olla käyttämättä mitään tietoja, joita voisi arvata. Eli käyttää pelkkää satunnaisuutta.

seppe [11.08.2010 14:49:10]

#

Olisiko seuraava menetelmä turvallisempi?

Kirjauduttaessa tallennetaan tietokantaan IP osoite, browser headerit, voimassaolo ja käyttäjä joilla on kirjauduttu ja luodaan uniikki tunniste joka tallennetaan evästeeseen ja tietokantaan. Jos IP tai browser headrit ovat muuttuneet, niin käyttäjä kirjattaisiin ulos.

Grez [11.08.2010 14:57:53]

#

Suunnilleen noin minä sen tekisin, paitsi että mielestäni tuossa selaimen tunnistetietojen tallentamisessa ei ole ihan hirveästi ideaa.

Hyökkääjä pystyy ne määrittämään mieleisikseen ja jos hyökkääjä saa käsiinsä tuon uniikin tunnisteen, niin luultavasti sillä on hallussaan myös käyttäjän selaimen tunnistetiedot. Eli tuon tuoma lisäturva on lähinnä plaseboa.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta