Denial-of-Service- und Objekterstellungs-Sicherheitslücken in JSON (CVE-2013-0269)

Es ist möglich, einen Denial-of-Service- und Objekterstellungs-Angriff auf die mit Ruby ausgelieferte json-Bibliothek durchzuführen. Dieser Sicherheitslücke wurde die CVE-Nummer CVE-2013-0269 zugewiesen und wir empfehlen dringend, Ruby zu aktualisieren.

Details

Beim Parsen gewisser JSON-Dokumente kann das json-Gem (auch das mit Ruby mitgelieferte) dazu gebracht werden, Ruby-Symbole in ein Zielsystem einzuschleusen. Da Ruby-Symbole bekanntlich nicht von der Garbage Collection betroffen sind, kann dies für einen Denial-of-Service-Angriff ausgenutzt werden.

Dieselbe Technik kann genutzt werden, um auf einem Zielsystem Objekte zu erstellen, die sich wie interne Objekte verhalten. Diese erscheinen nach außen hin normal, können aber zur Umgehung bestimmter Sicherheitsmechanismen benutzt werden und damit als Sprungbrett für SQL-Injection-Angriffe in RubyOnRails dienen.

Betroffener Code sieht so aus:

JSON.parse(user_input)

Wobei die user_input-Variable ein JSON-Dokument hält, das etwa so aussieht:

{"json_class":"foo"}

Das JSON-Gem wird daraufhin versuchen, die Konstante foo nachzuschlagen und dabei ein Symbol erzeugen.

In json Version 1.7.x können Objekte mit beliebigen Attributen wie folgt erstellt werden:

{"json_class":"JSON::GenericObject","foo":"bar"}

Dieses Dokument erzeugt eine Instanz von JSON::GenericObject mit einem Attribut foo, das den Wert "bar" hält. Durch die Instanziierung solcher Objekte können beliebige Symbole erzeugt werden und in einigen Fällen sogar Sicherheitsmechanismen umgangen werden.

BITTE BEACHTEN: Dieses Verhalten ändert sich nicht bei der Verwendung von JSON.load. JSON.load sollte man niemals Input aus nicht vertrauenswürdigen Quellen übergeben — wenn Se JSON aus nicht vertrauenswürdigen Quellen verarbeiten, benutzen Sie immer JSON.parse.

Alle Nutzer eines betroffenen Release sollten entweder aktualisieren oder einen der folgenden Workarounds umgehend anwenden.

Workarounds

Nutzer, die Ruby oder das JSON-Gem nicht aktualisieren können, sollten ihren Code von diesem:

JSON.parse(json)

auf diesen ändern:

JSON.parse(json, :create_additions => false)

Wenn Sie den JSON.parse nutzenden Code nicht anpassen können (weil Sie zum Beispiel ein Gem wie multi_json verwenden, das von JSON.parse abhängt), verwenden Sie diesen Monkeypatch:

module JSON
  class << self
    alias :old_parse :parse
    def parse(json, args = {})
      args[:create_additions] = false
      old_parse(json, args)
    end
  end
end

Betroffene Versionen

  • Alle Versionen von Ruby 1.9 vor 1.9.3-p392
  • Alle Versionen von Ruby 2 vor 2.0.0-p0
  • Alle Trunk-Revisionen vor Revision 39208

Danksagung

Großer Dank geht an die folgenden Personen, die das Problem verantwortungsvoll gemeldet („responsible disclosure“) und mit dem Rails-Team zusammengearbeitet haben, um es zu beheben:

  • Thomas Hollstegge von Zweitag (www.zweitag.de)
  • Ben Murphy

Verlauf

  • Erstmals veröffentlicht: 2013-02-22 12:00:00 (UTC)