Truputį buvau padaręs atostogas RoR, kadangi turėjau darbelio. Šiandien pasidalinsiu žiniomis apie Rails aplikacijų saugumą.
Saugumo spragų galime rasti praktiškai visose web aplikacijose, ruby on rails nėra išimtis, tad nepamirškime pasirūpinti savo saugumu. Turbūt populiariausia spraga yra SQL Injekcijos (en. SQL Injections). Jei web aplikacija parametrus perduodamas iš nepatikimų šaltinių (pavyzdžiui formos) deda tiesiai į SQL, nepatikrinus SQL meta simbolių, kaip backslashai arba kabutės, blogasis lankytojas gali ‘patobulinti’ jūsų SQL užklausą ir sukurti duomenis su neteisingais duomenimis, arba perimti iš duomenų bazės slaptus duomenis.
Jei jūs naudojate apibrėžtas ActiveRecord funkcijas (atributai - attributes, išsaugojimas - save, ieškojimas - find) be jokių įrašymo sąlygų, limitų ar jūsų pačių SQL užklausų, ActiveRecord pasirūpina kabutėmis ir pavojingais simboliais jūsų duomenyse.
Jei ne, jūs turite įsitikinti jog stringai argumentams, kurie yra naudojami iš karto SQL užklausoms (kaip sąlygų, limitų ir rūšiavimo argumentams), neturi pavojingų simbolių.
Įvestų duomenų naudojamas sąlygose ir pan.
Neteisingas naudojimas
Įsivaizduokite webmail (web pašto) sistemą, kur vartotojas gali pasirinkti sąrašą el. laiškų pagal tam tikrą antraštę (subject). Užklausa atrodytų maždaug taip:
Email.find_all "owner_id = 123 AND subject = '#{@params['subject']}'"
Tai yra pavojinga. Įsivaizduokite jog vartotojas pasiunčia į subjectą stringą ” ‘ OR 1 —’ “; reziumė gautume užklausą tokią:
Email.find_all "owner_id = 123 AND subject = '' OR 1 --''"
“OR 1″ yra visada true. Dalis “–” pradeda SQL komentarą; viskas po jo bus ignoruojama. Rezultatas: vartotojas gaus visus el. laiškus esančius duomenų bazėje.
(Žinoma owner_id tikroje aplikacijoje bus dinamiškas, tiesiog čia panaudotas pavyzdukas, jog būtų paprasčiau suprasti.)
Teisingas naudojimas
subject = @params['subject']
Email.find_all [ "owner_id = 123 AND subject = ?", subject ]
Jei find_all argumentas yra array, o ne string, ActiveRecord įdės array elementus 2..n vietoje “?” pirmam elemente, įdės citavimo ženklus jei elementai yra stringai, ir cituos visus simbolius turinčius specialias reikšmes duomenų bazės adapteriui naudojamui Email modelio.
Jei jums nepatinka array sintaksė, jūs galite pats valdyti kabučių tvarkymą iškvietus modelio klasės quote() metodą. Jūs turite tai padaryti jei naudojate find_by_sql:
subject = params['subject']
Email.find_by_sql "SELECT * FROM email WHERE owner_id = 123 AND subject = #{Email.quote(subject)}"
Citavimo ženklai bus įdėti automatiškai Email.quote() pagalba, jei argumentas yra stringas.
Ištraukiam užklausas į modelio metodus
Jei jums reikia įvykdyti užklausą su panašiom opcijom keliose vietose kode, siūlau sukurti modelio metodą tai užklausai. Vietoje
emails = Email.find_all ["subject = ?", subject]
jūs galite apibrėžtini žemiau esantį klasės metodą modelyje:
class Email < ActiveRecord::Base
def self.find_with_subject(subject)
Email.find_all ["subject = ?", subject]
end
end
ir iškviesti taip:
emails = Email.find_with_subject(subject)
Šitaip jums nereikės rūpintis apie meta simbolius kai naudosite funkciją find_with_subject. Nepamirškite kad jūs visada turėtumėt įsitikinti ar toks metodo tipas negali ko nors ’sulaužyti’, kai yra iškviečiamas su nepatikimais argumentais.
Kitame straipsnyje pasistengsiu aprašyti Cross Site Scripting (CSS/XSS) pažeidžiamumus.
Už informaciją ačiū Agile Web Development with Rails ir Ruby on Rails
Ankstesni Ruby on Rails dienoraščio straipsniai:
1 diena
2 diena
2006-06-25 | 13:54
Dar pridėsiu, kad norint išvis išvengti tokio tipo bėdų geriausiai naudoti ORM’us (http://en.wikipedia.org/wiki/Object-relational_mapping). Aišku ORM’ai turi savų trūkumų :)
Naudingas straipsnis kuo beprogramuotumėte :)
2006-06-25 | 21:27
Vat būtent, kad šios bėdos nėra vien tik ROR ar PHP programuotojų bėdos. Tai rodo jog, kad ir kuo programuotumėt privalote žinoti ką darote ir su kuo galite susidurti. Na o visos šios žinios ateina su patirtimi :-) Kartais labai juokinga būna, kai pvz į darbą būna priimamas koks nors PHP programeris, kuris dirbdamas su savo pirma užduotimi, nieko netikrindamas includina failus, nurodomus per URL. Tada tenka garsiai juoktis :-)
2006-06-25 | 21:52
Jo reiks parašyt kokį straipsniuką apie pagrindines klaidas daromas php programerių…
2006-06-26 | 0:11
Aha parasykit apie sauguma koki staipsi nes pvz. padarai kanors ir nelabai zinai kaip ta dalyka apsaugoti.
2006-06-27 | 11:41
[…] Kaip ir žadėjau, pratęsiu straipsniuką apie Ruby on Rails saugumą. Vakar rašiau apie SQL Injekcijas, šiandien papasakosiu apie Cross Site Scripting (CSS/XSS) pažeidžiamumus. […]
2006-12-13 | 18:36
Šiaip norint išvengti SQL injekcijos patartina naudoti ne pacias užklausa, o naudoti stored proceduras:)