CGI-skript og webapplikasjoner har sitt grensesnitt ut mot hele verden; en samling som ikke nødvendigvis er like tillitsverdig. Ansvaret er ene og alene vårt for å gjøre våre programmer motstandsdyktige mot angrep, men Ruby tilbyr noen hjelpemidler.
En av de store sikkerhetsfarene er eksterne data: Alt av informasjon som kommer fra brukeren kan potensielt være livsfarlig, skrevet med bare den hensikt å ødelegge dagen din.
Ruby tilbyr en mekanisme som merker alle data fra eksterne kilder: tainting
. Det antyder hvorvidt data er "besudlet" eller "smittebærende", slik at du ikke kan stole på dem lenger enn du kan kaste dem.
1| print 'Skriv noe inn og trykk Return: ' 2| 3| # Brukerdata er svart som kull... 4| skitten = gets 5| puts 'Skitten brukerdata.' if skitten.tainted? 6| 7| pur = 'Literal data, hvit som sne.' 8| puts pur if not pur.tainted? 9| 10| # Tainting sverter av på andre objekter som lages med 11| # utgangspunkt i besudlede data. 12| puts 'Sverter av!' if (pur+skitten).tainted? 13| 14| # Vi kan gjøre ting eksplisitt tainted... 15| pur.taint 16| # ..og renvaske skitten data (dersom vi får lov). 17| pur.untaint |
Dette fungerer dog kun som øremerking og har lite innvirkning før det settes i en sammenheng hvor statusen tas hensyn til. Vi skrur opp paranoiaen et hakk og går til DefCon-1...
I Ruby finnes det en spesiell variabel $SAFE
som angir sikkerhetsnivået. I Ruby versjonene 1.6.* går verdien fra 0 til og med 4. (Se i
Programming Ruby kapittelet om
nedlåsing av Ruby for detaljer.)
Vanlige Ruby programmer kjører normalt med $SAFE==0
og eruby skript med $SAFE==1
per default, men det kan stilles på i konfigurasjonen. Man kan øke sikkerhetsnivået, men aldri senke det.
1| puts "Nåværende $SAFE-nivå: #{$SAFE}." 2| 3| filnavn = "/etc/hosts" 4| 5| # Eksempel på potensielt farlig operasjon. 6| print File.open(filnavn).read.size, " bytes lest.\n" 7| 8| # La oss simulere en ekstern kilde og øke paranoiaen litt. 9| filnavn.taint 10| $SAFE = 1 11| 12| begin 13| print File.open(filnavn).read.size, " bytes lest.\n" 14| rescue SecurityError => sec_err 15| puts sec_err #=> "Insecure operation - open" 16| end |
Men hva gjør vi med en besudlet String
da? For $SAFE
-nivåer under 3, kan man gjøre litt "vasking" av dataene og så kalle untaint
. For nivå 3 og oppover går det derimot ikke å kalle untaint
på objekter.