Umgehung von Object#taint in DL und Fiddle in Ruby (CVE-2013-2065)
Geschrieben von usa am 14.5.2013
Übersetzt von Marcus Stollsteimer
Es besteht eine Verwundbarkeit in DL und Fiddle in Ruby, wodurch als “tainted” eingestufte Strings unabhängig von dem durch Ruby festgelegten $SAFE-Level in Systemaufrufen verwendet werden können. Dieser Schwachstelle wurde die CVE-Nummer CVE-2013-2065 zugewiesen.
Auswirkungen
Native Funktionen, die mittels DL oder Fiddle von Ruby aus aufgerufen werden, überprüfen nicht den “taint”-Status der ihnen übergebenen Objekte. Dies kann dazu führen, dass als “tainted” eingestufte Objekte als Eingabe akzeptiert werden anstatt eine SecurityError-Ausnahme auszulösen.
Betroffener Code für DL kann etwa folgendermaßen aussehen:
def my_function(user_input)
handle = DL.dlopen(nil)
sys_cfunc = DL::CFunc.new(handle['system'], DL::TYPE_INT, 'system')
sys = DL::Function.new(sys_cfunc, [DL::TYPE_VOIDP])
sys.call user_input
end
$SAFE = 1
my_function "uname -rs".taintBetroffener Code für Fiddle kann etwa folgendermaßen aussehen:
def my_function(user_input)
handle = DL.dlopen(nil)
sys = Fiddle::Function.new(handle['system'],
[Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
sys.call user_input
end
$SAFE = 1
my_function "uname -rs".taintAlle Nutzer eines betroffenen Releases sollten dringend aktualisieren oder einen der folgenden Workarounds anwenden.
Beachten Sie, dass dies eine Verwendung von numerischen Memory-Offsets als Pointer-Werte nicht verhindert. Zahlen können nicht als “tainted” markiert werden, so dass Code, der einen numerischen Memory-Offset übergibt, nicht überprüft werden kann. Zum Beispiel:
def my_function(input)
handle = DL.dlopen(nil)
sys = Fiddle::Function.new(handle['system'],
[Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
sys.call input
end
$SAFE = 1
user_input = "uname -rs".taint
my_function DL::CPtr[user_input].to_iIn diesem Fall wird der Speicherort übergeben und der “taint”-Status des Objekts kann von DL / Fiddle nicht festgestellt werden. Überprüfen Sie in solchen Fällen den “taint”-Status der Benutzereingabe vor der Übergabe des Speicherorts:
user_input = "uname -rs".taint
raise if $SAFE >= 1 && user_input.tainted?
my_function DL::CPtr[user_input].to_iWorkarounds
Wenn ein Upgrade von Ruby nicht möglich ist, kann der folgende Monkeypatch als Notlösung verwendet werden:
class Fiddle::Function
alias :old_call :call
def call(*args)
if $SAFE >= 1 && args.any? { |x| x.tainted? }
raise SecurityError, "tainted parameter not allowed"
end
old_call(*args)
end
endBetroffene Versionen
- Alle Versionen von Ruby 1.9 vor Ruby 1.9.3 patchlevel 426
- Alle Versionen von Ruby 2.0 vor Ruby 2.0.0 patchlevel 195
- Alle Trunk-Versionen vor Revision 40728
Ruby 1.8 ist nicht betroffen.
Danksagung
Vielen Dank an Vit Ondruch für das Melden dieses Problems.
Verlauf
- Erstmals veröffentlicht am 2013-05-14 13:00:00 (UTC)
Aktuelle Neuigkeiten
Ruby 3.4.2 veröffentlicht
Ruby 3.4.2 wurde veröffentlicht.
Geschrieben von k0kubun am 14.2.2025
Ruby 3.2.7 veröffentlicht
Ruby 3.2.7 wurde veröffentlicht.
Geschrieben von nagachika am 4.2.2025
Ruby 3.3.7 veröffentlicht
Ruby 3.3.7 wurde veröffentlicht.
Geschrieben von k0kubun am 15.1.2025
Ruby 3.4.0 veröffentlicht
Wir freuen uns, die Veröffentlichung von Ruby 3.4.0 bekannt zu geben. Ruby 3.4 führt den it-Blockparameter ein, ändert Prism zum Standardparser, bietet Happy Eyeballs Version...
Geschrieben von naruse am 25.12.2024