| Ruby on Rails ja tietoturva |
|
|
|
| Kirjoittanut Lea | |
|
Parin viime vuoden aikana sanat "Ruby on Rails" ja sen lyhenne "RoR" ovat alkaneet yhä enemmän näkyä ohjelmistokehittäjien keskustelupalstoilla ja erilaisilla tekniikkafoorumeilla. Sanojen takana on Ruby-niminen ohjelmointikieli ja siihen liitetty Rails-niminen ohjelmistokehys eli framework, jonka pitäisi helpottaa ja tehostaa web-ohjelmointia. Ja nyt yli vuoden käytännön ohjelmointikokemuksen perusteella voin sanoa että niin se tekeekin. Rails-frameworkin oletukset ja tukirakenteet auttavat ohjelmoijaa keskittymään sovelluksen kannalta oleelliseen huolehtimalla perustoiminnallisuudesta. Tämä tarkoittaa sitä, että RoR-ohjelmoijan tuottavuus (esim. mitattuna luotuina ohjelman toimintoina per työpäivä) on huippuluokkaa. Mutta tietoturva-asiantuntijana olen sitä mieltä, että ohjelmistokehityksessä tulee ottaa huomioon muutakin kuin ohjelmoijan tuottavuus. Erityisesti web-sovellusten kehittämisessä tietoturvasta tulee ottaa hyvä ote heti alkuunsa. Mitä välineitä Ruby on Rails tarjoaa tietoturvan takaamiseksi sillä kehitettyihin palveluihin? Katsotaan tätä erikseen kolmen eri web-sovelluksen tietoturvaongelman kohdalta: 1) XSS.Cross-site scripting eli XSS -ongelma tulee esiin aina kun mitä tahansa ulkopuolelta tulevaa tietoa näytetään sellaisenaan sovelluksessa. Tällöin hyökkääjä voi antaa tällaisena näytettävänä tietona esim. Javascript-ohjelman, joka esim. varastaa selaimesta cookiet, joita taas voidaan käyttää pääsemään erilaisiin sovellusistuntoihin sisälle. Tämän ongelman perusratkaisu on paitsi suodattaa sisääntuleva tieto, myös olla näyttämättä mitään ulkopuolelta saatua sellaisenaan. Sisääntulevaa data voidaan suodattaa tietomallin eli luokan kuvauksessa asettamalla sisällölle validointisääntöjä ("validates_"-direktiivit, erityisesti "validates_format_of"). Esimerkiksi käyttäjätiedot sisältävässä User-mallissa voisi olla birthyear-niminen tietokenttä, jossa on tarkoitus säilyttää syntymävuosi. Tällöin voidaan mallissa määritellä, että kaiken tuohon kenttään säilytettävän tulee olla numeerista (validates_numericality_of) tai jopa niin, että syntymävuoden tulee olla tietyllä numerovälillä (validates_inclusion_of). Validates_format_of mahdollistaa säännöllisten lausekkeiden käytön syötteen muodon tarkistamisessa. Säännöllisten lausekkeiden käyttö tulisi perustua ns. sallittujen merkkien ("whitelist") käyttöön, jossa tarkasti kerrotaan sallitut merkit ja kaikki listan ulkopuoliset ovat kiellettyjä. Jos yritetään käyttää ns. kiellettyjen merkkien ("blacklist") tekniikkaa, siitä helposti unohtuu joku pois. Ongelma on se, että validointisääntöjä ei aina voi käyttää hyväksi. Ensinnäkin ne toimivat vain tiedolle, joka on menossa tietokantaan, eivät esim. tilapäismuuttujille. Toiseksi kaikelle datalle ei voi muodostaa pitäviä validointisääntöjä, esim. yleiset tekstikentät. Koska etukäteisvalidointia ei aina voida käyttää, meidän on ainakin varmistuttava siitä, ettei mahdollista hyökkääjältä saatua tietoa anneta eteenpäin puhdistamatta. Tähän tulee apuun käyttöliittymien apumetodi h. Kyllä, siis pelkkä h (tai no html_escape, jolla on lyhennys h). Käärimällä mikä tahansa muuttuja/tieto apumetodi h:n sisälle, se puhdistetaan vaarallisesta sisällöstä esim. muuttamalla < ja > -merkeiksi < ja > -merkkijonoiksi. Esimerkiksi jos halutaan näyttää artikkelin tekstisisältö: <div class="teksti" > 2) SQL injection.SQL-injection on ongelma kaikissa sovelluksissa, joissa otetaan käyttäjältä jotakin syötettä esim. web-lomakkeella ja muodostetaan sen avulla SQL-lause. Jos asiaan ei etukäteen paneuduta, voikin olla niin että käyttäjä onnistuu web-lomakkeella antamaan varsinaisen tietokantaan menevän datan sijasta merkkijonon, jonka ohjelma tulkitsee SQL-lauseeksi tai sen osaksi. Tällaisella merkkijonolla voi esim. dumpata koko käyttäjätietokannan salasanoineen tai jopa tuhota sen. Tätä voi hallita RoR-ohjelmissa kahdella eri tavalla. Ensimmäinen puolustuslinja on tietysti toimia ylempänä mainituilla validointisäännöillä, jolloin esim. numeeriseksi määriteltyyn kenttään käyttäjän antama SQL-injection -komento ei mene validoinnista läpi. Valitettavasti tätä ei aina voi käyttää. Tällöin on erityistä huomiota kiinnitettävä SQL-komennon muodostamiseen. Railsissa käyttäjän syötteellä parametroitu SQL-komento voidaan muodostaa usealla eri tavalla, mutta turvallisinta on antaa Railsin hoitaa parametroinnin käytännön toteutus ns. placeholder-mekanismilla. Esimerkiksi kaikkien tietyssä paikassa asuvien tietyn nimisten käyttäjien hakeminen parametrina saaduilla tiedoilla: clients = User.find(:all, :conditions => ["name = :name and country = :country" , params[:user]]) Tässä Rails osaa ottaa parametrina saadusta user-hashista name- ja country-kentät ja muodostaa niiden perusteella kyselyn. 3) Istunnonhallinta.Koska HTTP on tilaton protokolla, palvelun tulee itse pitää jonkinlaista kirjaa siitä, miten eri saadut GET/POST/yms-viestit liittyvät toisiinsa. Varsin usein tämä tapahtuu antamalla käyttäjälle cookie, jonka perusteella viestit liitetään toisiinsa yhdeksi istunnoksi. Näin myös Rails-sovelluksessa. Jos cookien saa käsiinsä tai sen pystyy arvaamalla muodostamaan, voi päästä kirjautumaan sovellukseen toisena käyttäjänä. Cookien muodostaminen ja suojaaminen on siis varsin tärkeä asia, jota tavallinen kehittäjä ei välttämättä valmisframeworkia käyttäessään edes ajattele, vaan toteaa että siitä huolehditaan hänen puolestaan. Rails 2.0:ssa tähän mekanismiin on tullut isoja muutoksia - eikä välttämättä hyvään suuntaan. Oletusarvoinen istunnon varastointimekanismi on nyt CookieStore, eli aikaisemmin palvelimella säilytetyt istuntomuuttujat on nyt alettu koodata sisään cookieen. Tällä on tiettyjä vaikutuksia tietoturvaan. Ensimmäinen ongelma on se, että cookien sisältämät istuntimuuttujat on vain BASE64-koodattu, ei salattu. Näinollen muuttujien sisältö on helposti nähtävissä. Niiden muokkaaminen on tosin vaikeampaa, sillä cookie on osittain suojattu salasanalla parametroidulla SHA512-hajautusfunktiolla. Joten ensimmäinen Rails 2.0 tietoturvatoimenpide on varmistua siitä, että SHA512:aan käytetty salasana on riittävän turvallinen. Sanakirjahyökkäys cookie-hashia vastaan on nimittäin varsin helppo toteuttaa. Aivan ensimmäiset Rails 2.0- versiot eivät millään tavalla ottaneet kantaa tähän salasanan turvallisuuteen, mutta nykyiset versiot pakottavat >30 merkin mittaiseen salasanaan. Lisäksi kannattaa miettiä, mitä tietoa cookie sisältää. Jos haluaa olla suojassa istunnon varastamiselta, kannattaa cookiessa pitää esim. clientin IP-osoitetta ja sisäänkirjautumisen yhteydessä hylätä väärästä osoitteesta tulevat pyynnöt. Uuden CookieStoren kanssa cookiessa ei tosin kannata olla mitään salassa pidettävää. Muita temppujaToki Rails-ohjelmoinnin tietoturvassa on paljon muutakin, mutta näiden kolmen osa-alueen huomioon ottamisella pääsee jo pitkälle. Lisäksi kannattaa erityisesti huomata Railsin pitkälle kehittyneet ja integroidut testausmahdollisuudet. Jos tietoturva on huolen aihe, suosittelen tekemään sarjan funktionaalisia tai integrointitestejä, joissa testataan että esim. valtuutta käyttäjä ei pääse tietoihin tai toimintoihin käsiksi. Tai että periaatteessa valtuutettu käyttäjä ei pääse näkemään tietoja, joihin hänellä ei ole oikeutta. Ruby on Railsin tietoturvatietoa saa lisää mm. lähteistä: http://www.rorsecurity.info ja http://www.quarkruby.com/2007/0/20/ruby-on-rails-security-guide
|
|
| Viimeksi päivitetty 08.02.2008 13:39 |


