Pagrindiniai web sistemų pažeidžiamumai Ir saugos būdai


7. Nesaugus šifruotų duomenų laikymas

 

Naudojant kriptografijos metodus neretai pasirenkami silpni algoritmai, nesaugiai generuojami raktai. Pasitaiko ir tokių situacijų kada talpinami slapti duomenys net nėra
šifruojami, daromos klaidingos prielaidos, kad nepageidaujami asmenys jų pasiekti negalės. Šifravimas gali būti įgyvendinamas neteisingai, pvz. su šifruotais
duomenimis kartu išsaugojamas ir jų šifro raktas.

Slaptažodžių saugojimui ir tikrinimui dauguma Web aplikacijų naudoja vienakryptes kriptografines maišos funkcijas (one-way cryptographic hash functions). Duomenų
bazėje paprastai yra išsaugojama tik slaptažodžio maišos reikšmė. Ideali kriptografinė maišos funkcija pasižymi šiomis savybėmis:

  1. Maišos reikšmė yra lengvai išgaunama pasirinkus bet kurį grynąjį tekstą (plain text).
  2. Žinant tik maišos reikšmę neįmanoma išgauti pirminio grynojo teksto.
  3. Neįmanoma pakeisti grynojo teksto nekeičiant jam atitinkančios maišos reikšmės.
  4. Neįmanoma rasti dviejų skirtingų grynųjų tekstų su ta pačia maišos reikšme.

Maišos funkcijoms taip pat priskiriama „lavinos efekto“ (avalanche effect)[16]
charakteristika, kurios dėka iš pažiūros labai panašiems pirminiams tekstams yra suteikiamos visiškai skirtingos maišos reikšmės. Sakoma, kad vieno bito pasikeitimas
iššaukia „laviną“ pasikeitimų visuose maišos reikšmės bituose. Apačioje pateikti beveik identiški slaptažodžių ir jų maišos reikšmių pavyzdžiai:

slaptazodis1 →
e7549a3d9272ca59f3b94776e79867f3e71e46ee5aa78eeaeceb88a7c6055c68

slaptazodis2 →
92ee526fedb1cc573742005d0ee791014a5480de4e04258917e12449edc77e97

Tinkamo maišos algoritmo grąžinamos reikšmės neišduoda jokios informacijos apie grynąjį tekstą.

Pagrindinė minėtos populiariosios slaptažodžių saugojimo bei tikrinimo schemos problema yra ta, kad kriptografinė maišos funkcija yra dažniausiai naudojama
tiesiogiai be jokių papildomų saugumo priemonių. Verta atkreipti dėmesį, kad kriptografinė maišos funkcija nebūtinai yra slaptažodžiams saugoti pritaikyta maišos
funkcija. Slaptažodžio maišos funkcija yra aukštesnio lygio schema, paprastai naudojanti kriptografinę maišos funkcija su papildomais, slaptažodžiams skirtais saugumo mechanizmais. Kriptografinės maišos algoritmai pasižymi didele sparta, palengvinančia jėgos metodu (bruteforce) slaptažodžius spėliojančių įsilaužėlių darbą. Pavyzdžiui, modernūs serveriai gali parinkti iš numerių ir mažųjų raidžių sudarytą šešių simbolių ilgio MD5 slaptažodį vos per keturiasdešimt sekundžių.
Slaptažodžių maišos funkcijos yra sukurtos dirbti lėtai, tam maišos funkcija gali būti iškviečiama daug kartų, taip prailgindama veikimo laiką (rakto ištempimo technika).
Nulaužti tą patį slaptažodį, išsaugotą naudojant slaptažodžių maišos funkcija bcrypt, moderniam serveriui prireiktų net dvylikos metų[17].

Slaptažodžius spėliojant jėgos metodu neretai talkina vaivorykštės lentelių (rainbow tables) technika, kuomet įsilaužėlis iš anksto sugeneruoja spėliojamų slaptažodžių maišos kodų grandinę, taip paspartindamas procesą. Dar didesnė problema yra ta, kad įsilaužėlis, sėkmingai iš maišos reikšmės nuspėjęs slaptažodį, gali lengvai atpažinti kada tas pats slaptažodis yra naudojamas kitur. Saugantis nuo šių problemų, slaptažodžio maišos funkcija dažniausiai yra naudojama kartu su papildomu druskos (salt) parametru. Druska tai atsitiktinė bitų seka, maišos funkcijoje pridedama prie slaptažodžio. Tokiu atveju minėtais tradiciniais metodais randant duotai maišos reikšmei atitinkantį grynąjį tekstą, slaptažodžio ir jo reikšmės nesutaps, nes nebus naudojamas privalomas druskos parametras. Žemiau pateiktos dvi paprastos Python funkcijos. Viena grąžina maišos kodo su druska reikšmę, o kita yra iškviečiama, norint patikrinti slaptažodį:

import base64
import hashlib
import os

def getdigest(password, salt=None):
    if not salt:
        salt = base64.b64encode(os.urandom(32))
    digest = hashlib.sha256(salt + password).hexdigest()
    return salt, digest

def ispassword(password, salt, digest):
    return getdigest(password, salt)[1] == digest

Pavyzdys pateiktas tik norint iliustruoti druskos reikšmės vaidmenį tokiose schemose. Dėl per didelės spartos problemos, minėtos anksčiau, ši schema yra nesaugi.

Prie jau minėtų problemų neretai prisideda silpni, neteisingai pasirinkti kriptografijos algoritmai. Populiarioje maišos kodo funkcijoje MD5 jau seniai buvo rasti atvejai kuomet keletui pirminio teksto reikšmių buvo priskiriamos tos pačios maišos reikšmės. Šiem konfliktam (collisions) rasti yra taikomos specialios atakos[29].
Nors slaptažodžio schemai šios atakos reikšmingos įtakos paprastai nedaro, vertėtų atminti, kad pats MD5 algoritmas netenkina vienos iš esminių kriptografinės maišos
funkcijos charakteristikų, todėl jo naudojimas yra potencialiai pavojingas.

Saugiam slaptažodžių ar kitų slaptų duomenų saugojimui rekomenduojama naudoti standartines, jau patikrintas schemas bei algoritmus. Minėtoms slaptažodžių saugojimo schemų problemomis išspręsti, rekomenduojama naudoti adaptyvias maišos funkcijas, specialiai sukurtas slaptažodžių saugojimui (pvz. bcrypt). Mozilla siūlo naudoti bcrypt kartu su HMAC[21] operacija dėl šių priežasčių:

  • bcrypt maišos mechanizmas veikia sugaišdamas tam tikrą laiko tarpą, kad būtų apsunkinamos spėliojimo atakos.
  • bcrypt veikimo laikas gali būti prailgintas ir pritaikytas apsaugai nuo galingesnės įrangos.
  • HMAC operacijai reikalingas papildomas raktas yra laikomas ne duomenų bazėje. Taip sistemos apsauga yra padidinama tais atvejais kuomet įsilaužėlis atskleidžia
    duomenų bazės turinį (pvz. SQL įterpties atakomis).
  • HMAC operacija bcrypt maišos funkcijai prideda antraeilę apsaugą. Net ir radus bcrypt funkcijos pažeidžiamumų sistemos saugumas yra dalinai išlaikomas.