Pradinis puslapis > IT, Verslas ir ekonomika > Web mokėjimų saugumas: ką reiktų žinoti programuotojui

Web mokėjimų saugumas: ką reiktų žinoti programuotojui

2009-05-12 21:45
Iš daddys.com

Iš daddys.com

Jau kurį laiką rašiau tai, apie ką mąstau. Tačiau senokai nerašiau to, ką žinau. Iš savo profesinės patirties. Tai šįkart įrašas būtent apie tai.

Noriu trumpai brūkštelti programuotojams apie svetainių, į kurias integruojami jų pačių kurti mokėjimo sistemų plugin‘ai, saugumo užtikrinimą. Arba tiems, kurie norėtų peržvelgti turimus plugin’us ir padidinti saugumo lygį iki maksimalaus. Taigi ši rašliava tiems, kurie žengia pirmuosius žingsnius programuodami web apmokėjimų siuntimą mokėjimų sistemoms ir tiems, kurie nori praplėsti savo žinias.

Įžangai – kaip dažniausiai vyksta tokie apmokėjimai. Kaip pavyzdį imsiu mokėjimų sistemą, prie kurios dirbu pats – mokėjimai.lt.
Taigi. Kliento svetainėje sugeneruojama forma, kurią pats naudotojas siunčia per savo naršyklę į mokėjimų sistemą. Tada mokėjimų sistema arba duoda ką pasirinkti, arba tiesiog nukreipia toliau į pvz. banką arba kitą mokėjimų tarpininką. Apmokėjus, naudotojas grąžinamas atgal į kliento svetainę, kuri dažniausiai jau žino apie apmokėjimą ir naudotojui praneša: Jūsų apmokėjimas patvirtintas! O tas “dažniausiai” reiškia, kad… Ne visi produktai yra pakankamai protingi ;)

Taigi taigi taigi. Mokėjimų sistema visad pasirūpina, kad jos siunčiama informacija būtų apsaugota ir visad tai būtų galima patikrinti jos kliento svetainės programinio kodo. Slidžiausia vieta yra ta, kai naudotojas gali keisti formos, siunčiamos į mokėjimų sistemą duomenis. T.y. dar vis kliento svetainėje.

Dažniausiai užsakymas yra siunčiamas plikas, be jokio kodavimo ir papildomos apsaugos iš mokėjimų sistemos. Mes ir šitai planuojame greitu metu išspręsti, bet kiek esu tyrinėjęs kitas sistemas – tai yra gan plika.

Iš esmės to daryti lyg ir nereikia. Užsakymas – tiesiog informacija, pagal kurią mokėjimų sistema sugeneruoja užklausą į pvz. banką. O po to jau ar naudotojas apmoka ar ne – kitas klausimas. Nieks nieko nepralaimi, nuostolių nepadarysi.

Bet! Įvertinkite tokį variantą: svetainės sugeneruotoje užsakymui Nr.1 mokėjimo formoje naudotojas, prieš siųsdamas ją į mokėjimų sistemą, pakeičia kainą iš, tarkime, 100Lt į 5Lt. Apmoka. Mokėjimų sistema praneša – “Apmokėjimas užsakymui Nr.1 įvykdytas sėkmingai. Mūsų mokėjimo ID yra 1425345, suma: 5Lt, apmokėjimas atliktas <data>”.

Puiku! Apmokėjimas atliktas! Tik vat suma skiriasi… Atrodytų, viskas aišku – tokio mokėjimo nepriimti. Tačiau patikėkit manimi – tai aišku yra tol, kol aš viską čia ne per daugiausiai supintai papasakoju. Kiek out there, in the internet yra svetainių, kurios džiaugiasi gautu apmokėjimu ir nenaudoja papildomo tikrinimo – statistika. Tačiau pasinaudojus, kad ir 1 svetainės “skyle” galima jai padaryti nuostolių.

Aišku, ne visi (protingi) internetiniai blogiukai taip darytų. Reikėtų dar pasistengti maskuoti savo identitetą, nes tokia veika turėtų būti traktuojama kaip nusikalstama. Ir t.t. Bet nebūkime prasto kodo rašytojai (nes pvz. prastų knygų sėkmė nelydi), o pasistenkime apsisaugoti nuo visų galimų.

Mano rekomendacijos:

  • Programuojant visada naudotis puikiu kokybės garantu: Never trust user input. Šiuo atveju nevertėtų tikėti duomenimis, kurie bus inputinami ne vien į kliento, bet ir į mokėjimų sistemos serverį.
  • Visada tikrink, ar gavai tai, ko tikiesi. Jei tai turi būti skaičius – tikrink. Jei tai skaičius, tekstas ar bet kas į duombazę – escapeink (ne su addslashes(), o su tam skirtom priemonėm). Kaip Audrius minėjo savo mokymuose – jeigu yra klaida, jos neapdorok, o atsisakyk tolimesnio vykdymo. Puikus patarimas, kurio esmė pastebima įgyjant patirties.
  • Naudokis aukščiausio lygio įmanomomis apsaugomis. Pvz. mokėjimai.lt siūlo galimybę tikrinti SSL technologija pasirašytą informaciją, bei prastesnę apsaugą garantuojantį metodą. Būtinai naudok truputį sudėtingiau įgyvendinamą ir suprantamą, tačiau daug saugesnį būdą! Taip būsi įsitikinęs, kad gavai būtent tai, ko tikėjaisi.
  • Visada tikrink, ar gavai tai, ką siuntei mokėjimų sistemai. Mano minėtu atveju užtektų pagal užsakymo numerį tikrini sumą. Yra ir kitas, geresnis variantas: pvz. mokėjimai.lt grąžina visus nestandartinius (į specifikaciją neįtrauktus) parametrus nepakeistus kliento svetainei. Tuo galima puikiai pasinaudoti, sugeneruojant MD5 haš’ą iš svarbiausių mokėjimo duomenų (kainos, valiutos, užsakymo numerio) ir kelių slaptų duomenų (kurių nežino nieks, išskyrus pačią generuojančią sistemą – na ir tave, programuotoją). Grįžtant apmokėjimui, turi būti vėl sugeneruojamas haš’as pagal užklausoje esančias viešus ir slaptus, tik tau žinomus, parametrus ir jis sulyginamas su gautuoju. Jeigu šie duomenys sutampa – you’re good to go!
  • Ir pabaigai: tikrink, ar mokėjimas sėkmingas :) Jeigu mokėjimų sistema informuoja ir apie nesėkmingus mokėjimus (kad pvz. nuimti prekės rezervaciją ir būtų galima ją parduoti kam nors kitam), tai tikrink! Patikėkite manim – būna svetainių, kurios tik laukia užklausėlės į skriptelį su užsakymo numeriu ir viskas – praleidžia apmokėjimą kaip sėkmingą. Nors ir pati mokėjimų sistema pasakė: naudotojas neapmokėjo. Ot!

Būkit budrūs. Galit žaisti su “O gal nieks manęs nebandys apgauti..?”, tačiau jeigu galima apsidrausti – tai padaryti būtina, nes po to bus… Apmaudu :) Geriausiu atveju.

IT, Verslas ir ekonomika , ,

  1. 2009-05-14 14:26 at 14:26 | #1

    Bankinės sistemos (IB Pay pagrindu) naudoja HMAC duomenų patvirtinimą. Tai yra viešojo rakto kriptografijos principu pasirašomi duomenys, taip užtikrinant jų autentiškumą tarp banko ir kliento. Teoriškai tam pakanka ir self-signed SSL sertifikato, tik dabar SEB bankas reikalauja, jog kliento pusėje būtų HTTPS’as.

    Nereikia išradinėti dviračio.

    Beje, kalbant apie EVP, labai drįsčiau abejoti mokejimai.lt saugumu, kas tokioje sistemoje turi būti prioritetas.

    Dar, EVP OpenID implementacija kelia šypseną. Tai, jog prie jūsų projektų (eparasas.lt) galima prisijungti TIK su manoid.lt OpenID paneigia visus OpenID, kaip decentralizuotos vartotojų autentifikacijos sistemos, principus.

    Jums turėtų būti gėda prieš visą OpenID bendruomenę dėl tokio žingsnio, o juolab žinant, kad naujose asmens tapatybės kortelėse yra įdiegtas OpenID palaikymas su PAPE, savo sistemos protegavimas turėtų būti netoleruotinas, kai kalba eina apie OpenID.
    Siūlyčiau rašyti “Prisijunk su manoid.lt”, vietoje “Prisijunk su OpenID”.

  2. 2009-05-15 12:59 at 12:59 | #2

    Kaip tik teko integruoti mokejimai.lt savo projekte, tai norėčiau pakomentuoti:

    1. Labai gerai, kad radau šį įraša, būtinai reikės padaryti kainos ir merchanid sutikrinimą. Tačiau kodėl šią informaciją radau kažkokiam bloge, o ne mokejimai.lt specifikacijoje, kur jai ir turėtų būti vieta? Nesirūpinama klientų saugumu?

    2. Vistik aš matau čia mokejimai.lt design flaw. Suprasčiau, jei to išvengti nebūtų įmanoma, bet imkime tą pačią Pauliaus minėtą IB Pay sistemą (apie kurią mokejimai.lt tikrai turi gerai žinoti) – akivaizdžiai saugesnis sprendimas. Kodėl tiesiog nepaprašius kliento pasirašyti savo užklausą ir patikrinti jos jo viešu sertifikatu? Joks užklausos duomenų redagavimas nepraeis.

    3. Kodėl savo viešo sertifikato nepateikus normaliai specifikacijoje ir normaliai neparašius kaip formuojamas tikrinamas string’as užuot pateikus jį kažkokiam PHP kode. Ne visi programuoja PHP, tai bereikalingas laiko gaišimas aiškinantis kaip tas string’as formuojamas…

  3. 2009-05-15 16:04 at 16:04 | #3

    @Paulius
    Dviračio neišradinėju, tiesiog pasiūliau vieną variantą. Ir jis įgyvendinamas ne vien mokėjimai.lt sistemoje, taip pat ir pvz. wmtransfer.com sistemoje ir kitur.

    Dėl ManoID naudojimo: vienintelis skirtumas yra tas, kad ManoID turi galimybę patikimai identifikuoti asmenį – t.y. galima per bankinę sistemą pasitvirtinti savo tapatybę ir manoID sąskaita bus “krūta”. O minimas krūtumas pasireiškia tuo, kad tai yra *saugus* būdas identifikuoti save, per kurį netgi leidžiama el. būdu pasirašinėti dokumentus.

    Paprasčiausiai negalima leisti bet kam jungtis prie tokios sistemos. O su manoID sąskaita galima jungtis visur, kur palaikomas OpenID protokolas.

    Pripažįstu, kad pavadinimas netinkamas… Nes faktai neatitinka teksto. Ačiū už pastabą :)

    @Saulius
    1. “Kažkoks blogas” yra mano asmeninis blogas. O ką aš jame rašau – taip pat mano asmeninis reikalas. Kaip supratau, čia akmuo į mokėjimai.lt daržą (o ne į mano), kad pateikia mažiau info, nei galima rasti internete. Bet taip bus visad :) Kita vertus, ačiū už pasiūlymą – visgi ten šiuo metu dirbu.

    2. Iš dalies pritariu, kad tai design flaw. Kita vertus, programuotojai turėtų atlikti kokybišką darbą ir tikrinti tai, ką paminėjau įraše. Ne vien šiuo, o visais atvejais. Bent toks mano požiūris į kokybišką programavimą.

    O dėl pačios private/public raktų parašų technologijos, tai manau, kad greitu metu tai bus pritaikyta. :)

    Bet vėlgi: taip bus eliminuojama galimybė “piktam naudotojui” pakeisti duomenis. Tačiau nesudėtingo loginio tikrinimo pagalba tą gali daryti dabar ir pati svetainė.

    3. Geras pastebėjimas, ačiū! Reiks pateikti atskirame faile.

  4. 2009-05-15 16:54 at 16:54 | #4

    @Paulius
    Su eparasas.lt ir OpenID yra viskas gerai, pasiskaityk, kas yra SREG: http://openid.net/specs/openid-simple-registration-extension-1_0.html

  5. 2009-05-19 17:00 at 17:00 | #5

    @Mantas
    O prie ko čia sreg’as, jei negaliu su kito tiekėjo OpenID (apart manoid.lt) prisijungti apskritai.

    @Stepas
    Šaunu, kad manoid.lt turi asmens tapaybės patvirtinimo galimybę (per e-bankus).

    Naujo pavyzdžio asmens tapatybės kortelės su mikrochemomis turi skaitmeninį parašą ir validų OpenID, tad žiūrint į perpektyvą galėtumėte nepraleisti to pro akis :)
    Plačiau: http://www.lescinskas.lt/lt/blog/entry/paulius/naujose-asmens-tapatybes-kortelese-skaitmeniniai-sertifikatai-ir-openid-palaikymas

  6. 2009-05-20 11:02 at 11:02 | #6

    @Paulius
    Esmė tame, kad manoid.lt yra lygiai toks pats OpenID provideris, kaip ir visi kiti, tik tiek, kad turi papildomą galimybę pateikti daugiau duomenų, tokių kaip asmens kodas ir pan. Bet kuris kitas OpenID provideris, gali daryti tą patį. Yra daug OpenID providerių, kurie pateikai el. pašto adresą ar kitus konfigūruojamus duomenis, kuriuos naudotojas gali perduoti kitai svetainei ir tie duomenis iš karto panaudojami registracijos formoje ir pan.

  7. 2009-05-20 11:27 at 11:27 | #7

    Papildant Manto žodžius: jeigu egzistuotų kitas OpenID provaideris, galintis pasiūlyti tokio pat aukšto lygio unikalų naudotojo identifikavimą, tikiu, kad būtų svarstoma galimybė leisti jungtis ir per jį.

    O kol to nėra – viskas čia gerai. Vienintelis blogis, čia aprašytas, tai kad siūlome jungtis su OpenID, nepabrėždami, kad jis turi būti toks ir anoks krūtas.

    Kalbant dėl asmens tapatybės korteles, tai true – šis būdas taip pat užtikrina naudotojo identifikavimą aukšto saugumo reikalaujančiose sistemose. Būtinai reikės jį svarstyti kaip galimybę, ar net būtinybę.

    …įrašo komentarai nušoko nuo įrašo temos :)

  8. Tadas
    2009-07-06 22:58 at 22:58 | #8

    Man irgi kelia didelių abejonių mokejimai.lt saugumas. Prieš kelias savaites ten nusiresetinau passwordą ir… jie atsiuntė seną passwordą… Reiškia, passwordai saugomi plain textu… Tai apie kokį saugumą mes kalbam?

    P. S. pritariu postui, kuriame stebimasi, kad šitas straipsnis nėra publikuojamas mokejimai.lt

  9. 2009-08-26 00:43 at 00:43 | #9
  10. 2009-11-30 13:47 at 13:47 | #10

    Esu apie mokejimai.lt užvedęs temą: http://www.uzdarbis.lt/index.php?showtopic=101035

    Labai rekomenduoju prieš naudojantis jų paslaugomis pasverti, ar jūsų duomenys/informacija Jums yra svarbūs ir ar nieko nenutiks blogo, jeigu jie pateks į internetą… (-;

  1. Atsekčių dar nėra.