Ditulis oleh usa tanggal 2013-05-14
Diterjemahkan oleh catcyborg
Ada kelemahan pada DL dan Fiddle di Ruby di mana string yand di-taint dapat digunakan pada system call, terlepas dari tingkat $SAFE yang diset di Ruby. Kelemahan ini sudah di-assign dengan identifier CVE-2013-2065.
Dampak
Fungsi native yang di-expose ke Ruby dengan DL atau Fiddle tidak melakukan pengecekan terhadap nilai taint yang diset pada suatu object. Ini dapat mengakibatkan object yang di-taint tersebut diterima sebagai input ketika seharusnya exception SecurityError terjadi.
Berikut ini contoh kode DL yang memiliki kelemahan tersebut.
def fungsiku(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
fungsiku "uname -rs".taint
Berikut ini contoh kode Fiddle yang memiliki kelemahan tersebut.
def fungsiku(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
fungsiku "uname -rs".taint
Semua pengguna yang menjalankan rilis yang memiliki kelemahan ini sebaiknya meng-upgrade atau menggunakan solusi lain secepatnya.
Ingat bahwa ini tidak menghindari offset memory numerik dari digunakan sebagai nilai pointer. Angka tidak dapat di-taint, jadi kode yang memberikan offset memory numerik tidak dapat dicek. Contohnya:
def fungsiku(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
fungsiku DL::CPtr[user_input].to_i
Dalam hal ini, lokasi memory diberikan, dan Dl/Fiddle tidak dapat memastikan bahwa object itu di-taint. Harap cek nilai taint dari input user sebelum memberikan lokasi memory.
user_input = "uname -rs".taint
raise if $SAFE >= 1 && user_input.tainted?
fungsiku DL::CPtr[user_input].to_i
Solusi-Solusi Lain
Jika Anda tidak dapat meng-upgrade Ruby, monkey patch di bawah ini dapat digunakan sebagai solusi lain.
class Fiddle::Function
alias :old_call :call
def call(*args)
if $SAFE >= 1 && args.any? { |x| x.tainted? }
raise SecurityError, "parameter yang sudah di-taint tidak diizinkan"
end
old_call(*args)
end
end
Versi-Versi yang Terpengaruh
- Semua ruby versi 1.9 sebelum ruby 1.9.3 patchlevel 426
- Semua versi 2.0 sebelum 2.0.0 patchlevel 195
- sebelum trunk revisi 40728
Ruby versi 1.8 tidak terpengaruh.
Credits
Terima kasih kepada Vit Ondruch untuk menginformasikan masalah ini.
History
- Originally published at 2013-05-14 13:00:00 (UTC)