Open Source im professionellen Einsatz

Ruby on Rails: Cross-Site-Scripting durch Fehler in Übersetzungsmodul

Eine Schwachstelle im Ruby-on-Rails-Modul zur Internationalisierung hat zur Folge, dass ein entfernter Angreifer Cross-Site-Scripting-Attacken durchführen kann.

Das Rails-API zur Internationalisierung (I18n) ermöglicht es, auf einfache Art Programme für verschiedene Landessprachen zu entwickeln. Ruby on Rails stellt zum eigentlichen Übersetzen auch eine Helper-Funktion namens "translate()" bereit, die im "TranslationHelper"-Modul in der Datei "rails/actionpack/lib/action_view/helpers/translation_helper.rb" implementiert ist. Neben der eigentlichen Übersetzung
durch das I18n-API erledigt diese Funktion noch drei weitere Aufgaben: Zunächst gibt sie die Option ":rescue_format => :html" an I18n weiter, um "MissingTranslation"-Nachrichten abzufangen. Daneben vervollständigt sie auch Key-Partials und markiert den zurückgelieferten String als HTML-sicher, falls die Datei auf das Suffix "_html" oder ".html" endet. Ein so markierter String wird dann von anderen HTML-Funktionen im Weiteren nicht mehr escaped, da sie ihn als sicher ansehen. Die Kontrolle, ob die Datei HTML-sicher ist, erfolgt in der Funktion "html_safe_translation_key?()", die ein einfaches Pattern-Matching auf das Suffix vornimmt:

def html_safe_translation_key?(key)
 key.to_s =~ /(\b|_|\.)html$/
end

Sowohl die Translate-Helper-Funktion als auch das I18n-API selbst unterstützen außerdem die Interpolation von Variablen in die Übersetzung, womit sich beispielsweise String-Variablen in den Übersetzungsstring einfügen lassen. String-Interpolation unter Ruby erlaubt, einfach Variablen in einen String einzufügen, wie in folgendem Beispiel:

variable = 'World'
puts "Hello, #{variable}!" 

Solche Interpolation-Strings kann man der Methode "translate()" als Optionen übergeben:

def translate(key, options = {})
  options.merge!(:rescue_format => :html) unless options.key?(:rescue_format)
  ...

Und hierin besteht nun die Gefahr: Denn "translate()" markiert den String immer als HTML-sicher, wenn das Suffix stimmt. Dabei wird nicht überprüft, ob der via Interpolation eingefügte String ebenfalls HTML-sicher ist. Sollte diese Variable benutzerdefiniert sein, so kann ein Angreifer damit HTML-Code in die Übersetzung einschleusen, ohne dass dieser sauber escaped wird. Dies könnte beispielsweise in folgendem Szenario geschehen:

translate('index.html', :username => userinput)

Hier wird der "username"-Variable "userinput" zugeordnet, was in diesem Fall eine benutzerdefinierte Zeichenkette ist, der über die URL übergeben wird. Der Angreifer könnte jetzt einfach eine URL mit HTML-Code generieren, und damit beispielsweise effektiv folgenden Code erzeugen:

translate('index.html', :username =&gt; '<b>my html hack</b>')

Dadurch würde dem Anwender direkt der HTML-Code angezeigt. Wie bei allen Cross-Site-Skripting-Attacken wird das Ganze erst gefährlich, wenn der Angreifer Javascript-Code einfügt.

Ein schneller Workaround für diese Sicherheitslücke besteht darin, alle interpolierten Strings manuell via "h()" zu escapen, etwa folgendermaßen:

translate('index.html', :username => h(userinput))

Bei "h()" handelt es sich um einen Alias für "html_escape()", das für das Escapen von Strings zuständigist. Ein ordentliches Patch für die Schwachstelle wurde in der Rails-Security-Liste veröffentlicht.

Betroffen sind die Versionen 3.0.0 bis 3.0.10, 3.1.0, 3.1.1 und 2.3.x.

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook