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, med verdier fra 0 til 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 "$SAFE == #{$SAFE}" 2| 3| def les_fil( filnavn ) 4| File.open(filnavn) do |fil| 5| print fil.read.size, " bytes lest.\n" 6| end 7| end 8| 9| filnavn = "/etc/hosts" 10| 11| # Eksempel på potensielt farlig operasjon. 12| les_fil( filnavn ) 13| 14| # La oss simulere en ekstern kilde og øke paranoiaen litt. 15| filnavn.taint 16| $SAFE = 1 17| 18| begin 19| les_fil( filnavn ) 20| rescue SecurityError => sec_err 21| puts sec_err #=> "Insecure operation - initialize" 22| 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.