SQL injection Lietuvos e-parduotuvėse

Kai duomenų bazė tampa atviru langu vagims

Prisimenu, kaip prieš keletą metų vienas pažįstamas e-komercijos startuolis džiaugėsi sėkmingu paleidimo savaitgaliu. Pirmadienį jie rado savo klientų duomenis parduodamus tamsiosiose interneto užkampėse. Problema? Banali SQL injection spraga, kurią bet kuris pradedantis pentesteris būtų aptikęs per penkias minutes. Deja, tai ne vienintelis toks atvejis Lietuvoje.

SQL injection (SQLi) išlieka viena populiariausių atakų prieš internetines parduotuves, nors apie šią grėsmę kalbama jau daugiau nei du dešimtmečius. Pagal OWASP Top 10 sąrašą, injection tipo pažeidžiamumai nuolat lieka tarp kritiškiausių saugumo problemų. O Lietuvos e-komercijos sektoriuje situacija yra… sudėtinga.

Kodėl Lietuvos e-parduotuvės vis dar pažeidžiamos

Lietuvos e-komercijos rinka auga sparčiai – per pastaruosius trejus metus apyvartos augimas siekė 20-30% kasmet. Tačiau kartu su augimu neretai ateina ir skubėjimas. Daugelis mažų ir vidutinių e-parduotuvių naudoja pasenusias WooCommerce, Magento ar custom PHP sistemas, kurios nebuvo atnaujintos metus ar net ilgiau.

Pagrindinės problemos, su kuriomis susiduriame:

Legacy kodas ir techninė skola. Nemažai Lietuvos e-parduotuvių veikia ant platformų, sukurtų 2010-2015 metais. Tuomet saugumo standartai buvo kitokie, o prepared statements nebuvo tokia savaime suprantama praktika kaip dabar. Kai verslas auga, niekas nenori „liesti veikiančios sistemos”, net jei ji pilna skylių kaip šveicariškas sūris.

Pigių sprendimų kultūra. Kai kurių įmonių požiūris į IT saugumą primena rusišką ruletę – „gal mus nepuls”. Saugumo auditas? Per brangu. Penetracijos testavimas? Nereikalinga prabanga. Kol kas veikia – tai gerai. Problema ta, kad sužinai apie spragą tik tada, kai jau per vėlu.

Programuotojų kompetencijos spragos. Ne paslaptis, kad Lietuvoje trūksta IT specialistų. Dėl to e-parduotuvių kūrimą kartais patiki junior developerams arba laisvai samdomiem freelanceriams, kurie ne visada turi pakankamai žinių apie saugų kodavimą. Rezultatas – pažeidžiamos sistemos, kurios laukia savo eilės būti nulaužtos.

Kaip veikia SQL injection atakos praktiškai

Pabandykime be sudėtingos techninio žargono. Įsivaizduokite, kad jūsų e-parduotuvės paieškos laukelis yra kaip sekretorės, kuri tiesiog perduoda jūsų žinutes vadovui. Jūs pasakote „Ieškau raudonų batų”, ji eina ir perduoda šią žinutę tiesiogiai. Viskas gerai.

Bet kas nutinka, kai kenkėjas vietoj „raudonų batų” įrašo: „raudonų batų’ OR ‘1’=’1”? Jei sistema nepasitikrina, kas jai perduodama, sekretorė nuneš šią žinutę tiesiogiai vadovui (duomenų bazei), ir staiga vietoj batų paieškos rezultatų gaunate VISUS duomenų bazės įrašus.

Štai realus pavyzdys, kaip tai atrodo kode:

„`php
$search = $_GET[‘search’];
$query = „SELECT * FROM products WHERE name LIKE ‘%$search%'”;
„`

Šis kodas tiesiog ima tai, ką vartotojas įvedė į paieškos laukelį, ir kala tiesiai į SQL užklausą. Jokios validacijos, jokios filtracijos. Kenkėjas gali įterpti savo SQL komandas ir gauti prieigą prie bet kokių duomenų – klientų vardų, pavardžių, el. pašto adresų, o kartais net slaptažodžių hash’ų ar mokėjimo informacijos.

Dar blogiau – per UNION based SQL injection galima sujungti kelias užklausas ir ištraukti duomenis iš visiškai kitų lentelių:

„`
‘ UNION SELECT username, password, email FROM users–
„`

Tokia užklausa gali atskleisti visą vartotojų lentelę. O jei administratoriaus slaptažodis buvo silpnas arba nenaudotas salt’as hash’inimui – žaidimas baigtas.

Realūs atvejai iš Lietuvos praktikos

Negaliu atskleisti konkrečių įmonių pavadinimų, bet galiu pasidalinti anonimizuotais atvejais, su kuriais teko susidurti konsultuojant ar girdint iš kolegų.

Atvejis Nr. 1: Drabužių e-parduotuvė. Vidutinio dydžio Lietuvos drabužių parduotuvė naudojo custom PHP sprendimą. Produktų filtravimo funkcija buvo pažeidžiama per GET parametrus. Užpuolikas per vieną vakarą ištraukė visą klientų duomenų bazę – apie 15,000 įrašų su vardais, pavardėmis, adresais ir telefono numeriais. Įmonė sužinojo apie incidentą tik po mėnesio, kai klientai pradėjo skųstis gaunantys phishing SMS žinutes.

Atvejis Nr. 2: Elektronikos prekių platintojas. Naudojo pasenusią Magento 1.x versiją su custom moduliais. Vienas iš modulių turėjo SQL injection spragą admin panelėje. Kadangi daugelis administratorių naudojo silpnus slaptažodžius, užpuolikas gavo pilną prieigą prie sistemos. Rezultatas – pakeistos produktų kainos, įterpti kenkėjiški skriptai, kurie vogė mokėjimo kortelių duomenis checkout puslapyje.

Atvejis Nr. 3: Maisto produktų pristatymas. Startup’as, kuris sparčiai augo pandemijos metu. Jų mobilioji aplikacija komunikavo su API, kuris neturėjo jokios input validacijos. Per API endpoint’us buvo galima vykdyti SQL injection atakas. Laimė, šiuo atveju spragą aptiko white hat hackeris ir pranešė įmonei prieš tai, kai ją išnaudojo kenkėjai.

Visi šie atvejai turi bendrą bruožą – spragos buvo elementarios ir lengvai išvengiamos, jei būtų laikomasi bazinių saugumo praktikų.

Kaip apsisaugoti: konkrečios rekomendacijos

Gerai, užtenka bauginimo istorijų. Pereikime prie to, ką realiai galite padaryti, kad jūsų e-parduotuvė netaptų lengva auka.

Naudokite prepared statements ir parametrizuotas užklausas. Tai yra aukso standartas. Vietoj to, kad tiesiogiai įterptumėte vartotojo įvestį į SQL užklausą, naudokite placeholders:

„`php
$stmt = $pdo->prepare(„SELECT * FROM products WHERE name LIKE ?”);
$stmt->execute([„%$search%”]);
„`

Šiuo atveju duomenų bazės variklis žino, kas yra užklausa, o kas – duomenys. Net jei kenkėjas įterptų kenkėjišką kodą, jis bus traktuojamas kaip paprastas tekstas, o ne SQL komanda.

Naudokite ORM (Object-Relational Mapping) bibliotekas. Eloquent (Laravel), Doctrine (Symfony), TypeORM (Node.js) – šios bibliotekos automatiškai tvarko SQL užklausų saugumą, jei jas naudojate teisingai. Jos abstraktuoja tiesiogines SQL užklausas ir sumažina riziką padaryti klaidą.

Validuokite ir sanitizuokite visą vartotojo įvestį. Niekada, NIEKADA nepasitikėkite tuo, kas ateina iš kliento pusės. Netgi jei tai atrodo kaip nekaltas paieškos laukelis. Naudokite whitelist požiūrį – leiskite tik tai, kas tikrai reikalinga, o ne blokuokite tai, kas atrodo įtartina.

„`php
$allowed_sort = [‘name’, ‘price’, ‘date’];
$sort = in_array($_GET[‘sort’], $allowed_sort) ? $_GET[‘sort’] : ‘name’;
„`

Taikykite least privilege principą duomenų bazėje. Jūsų web aplikacijos duomenų bazės vartotojas neturėtų turėti DROP, CREATE ar DELETE teisių, jei jos nereikalingos. Jei užpuolikas ir gautų prieigą per SQL injection, bent jau negalės ištrinti visos duomenų bazės.

Įdiekite WAF (Web Application Firewall). Cloudflare, Sucuri, AWS WAF – šie sprendimai gali aptikti ir blokuoti daugelį SQL injection bandymų dar prieš jiems pasiekiant jūsų serverį. Tai nėra 100% apsauga, bet papildomas apsaugos sluoksnis tikrai nepakenks.

Testavimas ir monitoringas

Apsauga be testavimo yra kaip draudimas be sąlygų skaitymo – manote, kad esate apsaugoti, bet realybė gali skaudžiai nustebinti.

Reguliarūs saugumo auditai. Bent kartą per metus turėtumėte atlikti profesionalų penetracijos testavimą. Taip, tai kainuoja pinigų (Lietuvoje – nuo 1000 iki 5000+ EUR priklausomai nuo sistemos sudėtingumo), bet tai daug pigiau nei duomenų nutekėjimo padariniai.

Jei biudžetas ribotas, galite pradėti nuo automatizuotų įrankių:

SQLMap – open source įrankis SQL injection pažeidžiamumų paieškai
OWASP ZAP – nemokamas web aplikacijų saugumo skeneris
Burp Suite Community Edition – populiarus įrankis saugumo testavimui

Šie įrankiai gali aptikti daugelį akivaizdžių spragų, nors ir nepakeis profesionalaus pentesterio.

Log’ų monitoringas ir anomalijų aptikimas. Turėtumėte stebėti įtartinus užklausų pattern’us savo sistemoje. Jei staiga matote daug užklausų su simboliais kaip ‘, –, UNION, xp_cmdshell – tai raudonos vėliavėlės.

Galite naudoti įrankius kaip:
– ELK stack (Elasticsearch, Logstash, Kibana)
– Graylog
– Splunk (brangesnis, bet galingesnis)

Arba bent jau sukonfigūruokite paprastus alert’us, kurie praneštų apie įtartinas užklausas.

Ką daryti, jei jau per vėlu

Tarkime, blogiausias scenarijus – sužinojote (arba įtariate), kad jūsų sistema buvo nulaužta per SQL injection. Pirmas impulsas – panika. Antras – bandymas nuslėpti. Abu neteisingi.

Nedelsiant izoliuokite pažeistą sistemą. Jei įmanoma, laikinai išjunkite svetainę arba bent jau pažeidžiamą funkciją. Taip, prarasite pardavimus, bet tai geriau nei toliau leisti vagims šeimininkauti jūsų sistemoje.

Išsaugokite įrodymus. Netrinkite log’ų, nedarykite skubotų pakeitimų. Jums gali prireikti šios informacijos tyrimui ar net teisiniams procesams. Padarykite pilną sistemos snapshot’ą.

Įtraukite specialistus. Jei neturite in-house saugumo ekspertų, samdykite išorinius. Lietuvoje yra keletas kompanijų, kurios specializuojasi incident response. Taip, tai kainuos, bet bandymas išsiaiškinti viską patiems gali tik pabloginti situaciją.

Informuokite paveiktus klientus. Pagal BDAR (GDPR), turite pranešti apie duomenų nutekėjimą per 72 valandas. Bet net be teisinių reikalavimų – tai tiesiog teisinga. Jūsų klientai turi teisę žinoti, kad jų duomenys galėjo būti pažeisti.

Analizuokite ir mokykitės. Po incidento atlikite išsamią post-mortem analizę. Kaip tai nutiko? Kodėl saugumo kontrolės nesuveikė? Ką galite pakeisti, kad tai nepasikartotų?

Kai saugumas tampa konkurenciniu pranašumu

Baigiant norėčiau pasidalinti mintimi, kuri galbūt skamba neįprastai: saugumas gali būti ne tik išlaida, bet ir investicija į jūsų verslo reputaciją.

Lietuvos e-komercijos rinkoje vis dar vyrauja požiūris, kad saugumas – tai kažkas, ką darai tik tada, kai privalai. Bet situacija keičiasi. Vartotojai tampa vis labiau susipratę apie duomenų apsaugą. Jie pastebi HTTPS, skaito privatumo politikas, domisi, kaip saugomi jų duomenys.

E-parduotuvė, kuri gali pasigirti saugumo sertifikatais, reguliariais auditais ir skaidria komunikacija apie duomenų apsaugą, išsiskiria iš konkurentų. Tai ypač aktualu B2B segmente, kur įmonės vis dažniau reikalauja iš partnerių atitikti tam tikrus saugumo standartus.

SQL injection prevencija nėra raketų mokslas. Tai ne kažkokia ezoterinė žinių sritis, prieinama tik elitiniams hackerių būreliams. Tai bazinė higiena, tokia pat svarbi kaip reguliarus sistemos atnaujinimas ar backup’ų darymas.

Taip, reikės investuoti laiko mokantis, galbūt perrašyti dalį legacy kodo, galbūt samdyti specialistus konsultacijoms. Bet alternatyva – rizikuoti visu verslu dėl spragos, kuri galėjo būti užkerta per kelias valandas – tiesiog neapsimoka.

Lietuvos e-komercija turi didžiulį potencialą. Mes turime talentingų programuotojų, inovatyvių verslininkų, augančią rinką. Būtų gėda, jei visa tai būtų pakenkta dėl elementarių saugumo klaidų, apie kurias IT bendruomenė kalba jau dvidešimt metų. Laikas žengti į priekį ir padaryti saugumą ne išimtimi, o norma.

Daugiau

Bun, Node ir Deno: vykdymo laiko karas