Değerlendirmeye benzeyen özellikler neden diğer olası zararlı özelliklerin aksine kötü kabul edilir?


51

(Nasılsa yorumlanır) En modern diller çeşit var eval işlevi. Böyle bir işlev, çoğu zaman bir dize olarak ana argüman olarak geçirilen keyfi dil kodunu çalıştırır (farklı diller, değerlendirme işlevine daha fazla özellik ekleyebilir).

Anladığım kadarıyla kullanıcıların bu işlevi yerine getirmelerine izin verilmemelidir ( düzenleme, yani iletilecek keyfi bir kullanıcıdan doğrudan veya dolaylı olarak rastgele girdi alma eval), özellikle de sunucu tarafı yazılımıyla, işlemi kötü amaçlı kod yürütmeye zorlayabileceklerinden eminim. Bu şekilde, öğreticiler ve topluluklar için bize değil eval kullanın. Ancak, birçok zamanlar vardır eval faydalı ve kullanılır:

  • Yazılım öğelerine özel erişim kuralları (IIRC OpenERP, ir.ruledinamik python kodunu kullanabilen bir nesneye sahiptir).
  • Özel hesaplamalar ve / veya ölçütler (OpenERP, özel kod hesaplamalarına izin vermek için böyle alanlara sahiptir).
  • OpenERP rapor ayrıştırıcıları (evet, sizi OpenERP olaylarından korktuğumu biliyorum ... ama sahip olduğum ana örnek bu).
  • Bazı RPG oyunlarında kod yazım efektleri.

Bu yüzden, doğru kullanıldığı sürece, iyi bir kullanımları vardır. En önemli avantaj, özelliğin yöneticilere daha fazla dosya oluşturmak ve bunları eklemek zorunda kalmadan özel kod yazmasına izin vermesidir (eval özelliklerini kullanan birçok çerçevenin de bir dosya, modül, paket, ... okuyabileceği bir yolu olmasına rağmen).

Bununla birlikte, eval popüler kültürde kötüdür. Sisteminize girmek gibi şeyler akla geliyor.

Ancak, kullanıcılar tarafından bir şekilde erişilirse zararlı olabilecek başka işlevler de vardır: bağlantıyı kes, oku, yaz (dosya anlambilimi), bellek tahsisi ve işaretçi aritmetiği, veritabanı modeli erişimi (SQL-enjekte edilebilir durumlar düşünülmese bile).

Yani temel olarak çoğu zaman hiçbir kod yazılmaz düzgün ya da değil izledi düzgün (kaynaklar, kullanıcılar, ortamlar, ...), kod kötülük ve hatta ekonomik etkiye yol açabilir.

Ancak evalfonksiyonlarla ilgili özel bir şey var (dilden bağımsız).

Soru : Bu korkunun, diğer muhtemel tehlikeli özelliklere aynı dikkati vermek yerine, popüler kültürün bir parçası haline gelmesinin tarihsel bir gerçeği var mı?


11
Bunun çok geniş olduğu konusunda hemfikir değilim ve delil olarak makul bir uzunluğa sahip olan dört cevabı sunuyorum.

12
Çok geniş kapatmak için mi oy kullandılar ? (Bu toplulukta henüz yakın oy göremiyorum) Bu yakın sebep, son zamanlarda hiçbir anlamı olmayan bir joker karakter haline geliyor. Özellikle sorduğum nokta, örneklerle ve sorulacak belirli bir nokta ile açıkça netleşiyorsa. Bu konuyu
Meta'da soracağım

13
Neden diğer popüler özelliklerden daha fazla dikkat çekerek popüler kültürün bir parçası haline geldi? Aliterasyon Çünkü eval - kötülük hatırlaması kolay
Bergi

5
Hafıza dağılımı ve işaretçi aritmetiği birçok kişi tarafından kötülük olarak görülür.
user253751

5
OpenERP (şimdi Odoo) 'nun sadece aramadığı değil , kodun tehlikeli şeyler yapmasını engellemek için çevreyi hazırlayan evaldahili bir işlevi safe_evalolduğu unutulmamalıdır. Python oldukça esnek bir dil olduğundan ve kontrol etmesi zor olduğu için hatalar bulundu.
André Paramés

Yanıtlar:


76

Tek evalbaşına bir işlev kötü değildir ve yaptığınıza inanmadığım ince bir nokta var:

Bir programın keyfi kullanıcı girişi yapmasına izin vermek kötü

Bir evaltür fonksiyon kullanan kod yazdım ve güvenliydi: program ve parametreler sabit kodlanmıştı. Bazen, programın ihtiyaç duyduğu şeyi yapmak için bir dil veya kütüphane özelliği yoktur ve bir kabuk komutu çalıştırmak kısa yoldur. "Bunu birkaç saat içinde kodlamayı bitirmem gerekiyor, fakat Java / .NET / PHP / hangi kodu yazsam iki gün sürecek. Ya da evalbeş dakika içinde yapabilirim ."

Kullanıcıların istedikleri herhangi bir şeyi uygulamalarına izin verdikten sonra, kullanıcı ayrıcalığı tarafından kilitlenmiş olsa veya "güvenli" bir ekranın gerisinde kalsanız bile, saldırı vektörleri yaratırsınız. Her hafta, bazı rastgele CMS'ler, blog yazılımı, vb. Bir saldırganın böyle bir delikten yararlanabileceği yamalı bir güvenlik deliğine sahiptir. rm -rf /Felaketle sonuçlanabilecek bir işleve veya başka bir şeye erişebilecek bir işleve erişimi korumak için tüm yazılım yığınına güveniyorsunuz (not: bu komutun başarılı olması muhtemel değildir, ancak bir miktar hasara neden olduktan sonra başarısız olur).

Bu korkunun, diğer olası tehlikeli özelliklere aynı dikkati vermek yerine, popüler kültürün bir parçası haline gelmesinin tarihsel bir gerçeği var mı?

Evet, tarihi bir emsal var. Uzaktan saldırganların keyfi kod çalıştırmalarına izin veren çeşitli yazılımlarda yıllar içinde düzeltilen çok sayıda hata nedeniyle, fikri evalçoğunlukla lehine düştü. Modern diller ve kütüphaneler evaldaha az önemli hale getiren zengin işlevsellik kümelerine sahiptir ve bu bir tesadüf değil. Her ikisi de fonksiyonların kullanımını kolaylaştırır ve istismar riskini azaltır.

Popüler dillerde potansiyel olarak güvensiz özelliklerin çoğuna dikkat edilmiştir. Birinin daha fazla ilgi görüp görmediği öncelikle bir fikir meselesidir, ancak evalözelliklerin kesinlikle anlaşılması kolay, kanıtlanabilir bir güvenlik sorunu vardır. İlk olarak, onlar işletim sistemini çalıştırmadan izin kabuk yerleşik ins ve standart (örneğin şunlardır harici programları da dahil olmak komutları rmya del). İki, diğer istismarlarla birleştiğinde, bir saldırgan kendi yürütülebilir veya kabuk komut dosyasını yükleyebilir ve daha sonra herhangi bir şeyin gerçekleşmesi için kapıyı açarak yazılımınız aracılığıyla yürütebilir (hiçbiri iyi değil).

Bu zor bir problem. Yazılım karmaşıktır ve bir yazılım yığını (örneğin LAMP ) birbiriyle karmaşık şekillerde etkileşime giren çok sayıda yazılım parçasıdır. Bunun gibi dil özelliklerini nasıl kullandığınıza dikkat edin ve kullanıcıların hiçbir zaman keyfi komutları çalıştırmalarına izin vermeyin.


2
Sen teksin :). Bu kültüre katkıda bulunan iyi bilinen bir örnek olsa da, cevabında görmek isterim.
Luis Masuelli

5
Tek bir örneğin farkında değilim , bunun daha az kullanılan istismar örnekleri ve yamalarla daha çok "bin kesik ölüm" olduğuna inanıyorum. Bazı uzaktan kullanımların haftalık olarak bazı yazılımlara eklendiğini söylediğimde abartmıyorum .

1
IDE, bana - kullanıcının - keyfi giriş yapmasını sağlayan bir program. Kötü değil faydalı buluyorum.
Den

3
@Den bu bir istisna olurdu. Bir IDE olarak, bu yetenek olmadan kargaşaya neden olabileceğinden eminim. Sadece kaynak koduna yaz. Ayrıca, üzerinde çalıştığı bilgisayara zaten tam erişiminiz var. Buradaki sonuç, bir ayrıcalık yükseltmekeval olabilir . eğer zaten yükseltilmişlerse bu sorun değil.

3
@Den: Raymond Chen'in "hava kilidinin diğer tarafı" olarak özetlediği şey. Zaten koşabilirsin rm -rf /, bunu IDE aracılığıyla karmaşık bir şekilde yapmaya gerek yok. Buradaki sorun, evalbu yeteneği, bu yeteneği olmayan bir çok aktöre açmasıdır.
MS’e

38

Bunun bir kısmı basitçe nüans zor. Hiçbir zaman, genel alanları kullanma, sql sorguları için string enterpolasyonu veya eval kullanmama gibi bir şey söylemek kolaydır. Bu ifadelerin, hiçbir koşulda, bunları kullanmak için bir neden olmadıklarını söylediği anlaşılmamalıdır. Ancak genel bir kural olarak bunlardan kaçınmak iyi bir fikirdir.

Değerlendirme, pek çok ortak konuyu birleştirdiği için şiddetle tavsiye edilir.

İlk olarak, enjeksiyon saldırılarına karşı hassastır. Burada, kullanıcı tarafından kontrol edilen veriler koda eklendiğinde, rastgele kodun yanlışlıkla girilmesine izin vermek kolayca SQL enjeksiyonu gibidir.

İkincisi, yeni başlayanlar, kötü bir şekilde yapılandırılmış kodu aşmak için eval'ü kullanma eğilimindedir. Yeni başlayan bir kodlayıcıya benzeyen bir kod yazabilir:

x0 = "hello"
x1 = "world"
x2 = "how"
x3 = "are"
x4 = "you?"
for index in range(5):
   print eval("x" + index)

Bu işe yarıyor ama bu sorunu çözmenin gerçekten yanlış yolu. Açıkçası, bir listeyi kullanmak çok daha iyi olurdu.

Üçüncüsü, eval tipik olarak verimsizdir. Programlama dil uygulamalarımızı hızlandırmak için çok çaba harcanıyor. Ancak, değerlendirmenin hızlandırılması zordur ve kullanmanın performansınız üzerinde tipik olarak zararlı etkileri olacaktır.

Öyleyse, eval kötü değildir. Değerlendirmenin kötü olduğunu söyleyebiliriz, çünkü onu koymak için akılda kalıcı bir yoldur. Yeni başlayan herhangi bir kodlayıcı kesinlikle değerlendirmeden uzak durmalıdır, çünkü ne yapmak istiyorlarsa yapsın, değerlendirme neredeyse kesinlikle yanlış bir çözümdür. Bazı gelişmiş kullanım durumları için, değerlendirme mantıklıdır ve kullanmanız gerekir, ancak açıkçası tuzaklar konusunda dikkatli olun.


13
İkinci vakan çok önemli. Sahip dillerde eval değişken referansı üretmek için bir dize değerlendirirken aynı zamanda derlenmektedir olmayan önemsiz olduğunu. Eğer Örneğin, var x = 3; print(x)bir derlenmiş sonra herhangi bir çalışma zamanı bilgisi olacaksa gerekmez kaynak adı "x" kullanılır. var x = 3; print(eval("x"))Çalışabilmek için bu haritalamanın kaydedilmesi gerekiyor. Bu gerçek bir meseledir: Common Lisp'te (let ((x 3)) (print (eval 'x)))sınırsız bir değişken istisnası atacak, çünkü sözcüksel değişken x , kod derlendikten sonra adla herhangi bir bağlantıya sahip değildir .
Joshua Taylor

@JohnuaTaylor İkinci nedeni değil üçüncü nedeni mi kastediyorsunuz ?
user253751

1
@ immibis, sanırım ikinci nedenden koda atıfta bulunuyor. Ama haklısın, bu gerçekten üçüncü nedenden kaynaklanıyor: performans.
Winston Ewert

Bu soruyu gördüm , değil mi? ;)
jpmc26

@ jpmc26, hayır. Ama bunun gibi çok şey gördüm.
Winston Ewert

20

Asıl mesele, “keyfi kod yürütme” nin “her şeyi yapabilmek” için teknoloji konuşması olmasıdır. Birisi kodunuzda rasgele kod yürütme işleminden yararlanabiliyorsa, bu mümkün olan en kötü güvenlik açığıdır, çünkü sisteminizin yapması mümkün olan her şeyi yapabilecekleri anlamına gelir .

"Diğer muhtemel zararlı böceklerin" de sınırları olabilir; bu, tanım gereği, istismar edilen bir kod yürütme işleminden daha az zarar verebilecekleri anlamına gelir.


2
Argüman uğruna, işaretçilerin kötüye kullanılması da keyfi kod uygulamasına yol açar , ancak işaretçiler olduğundan daha azına kaşlarını çattı eval.
Dmitry Grigoryev

12
@DmitryGrigoryev Gerçekten mi? C ++ dışında, işaretçiler genellikle son derece tehlikeli ve kaçınılmaz olarak kabul edilir. C #, örneğin işaretçileri destekler, ancak diğer tüm seçenekleri de tükettikten sonra deneyeceğiniz en son şey olma eğilimindedir (genellikle, veri manipülasyonundaki performans nedenleriyle). Çoğu modern dil, işaretçileri desteklemez. C ++ 'ın kendisi bile, sorunları rastgele işaretçilerle hafifletmeye çalışan "daha güvenli" işaretçilere doğru ilerliyor (örneğin, işaretçiler yerine gerçek listeler / diziler kullanarak, safe_ptr kullanarak, referans geçerken ...).
Luaan

2
@DmitryGrigoryev: İşaretçilerin değerlendirmeden daha tehlikeli olduğunu söyleyenlere referans verebilir misiniz?
JacquesB

2
@JacquesB işte burda :)
Dmitry Grigoryev

1
@ JacquesB, evet; şaka olarak düşünülmüştü (gülümsemenin yeterince açık olmasını beklerdim). OP bu açıklamayı yaptı, ben değil, ondan kanıt istemelisin.
Dmitry Grigoryev

15

Pratik ve teorik bir sebep var.

Pratik sebep, sık sık sorunlara neden olduğunu gözlemlememizdir. Değerlendirmenin iyi bir çözüm ile sonuçlanması nadirdir ve değerlendirmenin olmasaydı ve sorunu farklı bir şekilde ele aldıysanız, sonuçta daha iyi bir sonuç alacağınız kötü bir çözümle sonuçlanır. Bu yüzden basitleştirilmiş tavsiyeler bunu görmezden gelmektir ve basitleştirilmiş önerileri görmezden gelmek istediğiniz bir durum bulursanız, basitleştirilmiş tavsiyenin neden uygulanamadığını ve ortak olduğunu anlamak için yeterince düşündüğünüzü umalım. tuzaklar seni etkilemeyecek.

Daha teorik sebep, iyi kod yazmak zorsa, iyi kod yazan kod yazmanın daha da zor olmasıdır. Eval kullanıyorsanız veya dizeleri birbirine yapıştırarak veya bir JIT derleyicisi yazarak SQL ifadeleri oluştururken olsun, yapmaya çalıştığınız şey genellikle beklediğinizden daha zordur. Kötü amaçlı kod enjeksiyonu potansiyeli sorunun büyük bir bölümünü oluşturuyor, ancak bunun dışında, kodunuz çalışma zamanına kadar mevcut değilse, kodunuzun doğru olduğunu bilmek genel olarak zor. Bu yüzden basitleştirilmiş tavsiyeler, işleri kendiniz için daha kolay tutmaktır: "parametreli hale getirilmiş SQL sorgularını kullanın", "eval kullanmayın".

Büyü efektleri örneğinize göre: Oyun tasarımcılarına, büyü efektlerini tanımlamak için C ++ 'ya (ya da herneyse) daha kolay bir dil vermek için oyununuza bir Lua (ya da her neyse) derleyici ya da tercüman inşa etmek bir şeydir. Yaptığınız tek şey oyuna ya da DLC'ye ya da neye sahip olduğunuza yazılan, test edilen ve oyuna dahil edilen kodu değerlendirmek ise "değerlendirme sorunlarının" çoğu için geçerli değildir. Bu sadece dilleri karıştırıyor. Lua (veya C ++ veya SQL veya shell komutları veya her neyse) anında oluşturmaya çalıştığınızda büyük sorunlar sizi zorlar ve karıştırır.


1
Tabii ki, çalışma zamanı kod oluşturma yapabilirsiniz doğru yapılması ve eval olabilir yararlı olabilir. Örneğin, özellikle “temizleyici” bir OOP'tan veya işlevsel bir çözümden daha fazla performans istediğimde metaprogramlama / makro benzeri şeyler için eval kullanıyorum. Ortaya çıkan kod genellikle daha iyi ve basittir çünkü daha az kazan plakası vardır. Bununla birlikte, kumlama, kaçış mekanizmaları, kod enjeksiyonu, kapsam belirleme kuralları, hata raporlama, optimizasyon vb. İle ilgili çeşitli sorunların farkında olmak, dilde önemsiz bir yeterlilik düzeyi gerektirir ve değerlendirme, bu bilgi olmadan olumlu bir şekilde tehlikelidir.
amon

11

Hayır, bariz bir tarihsel gerçek yok.

Değerlendirmenin kötülükleri baştan görmek kolaydır. Diğer özellikler hafif tehlikelidir. İnsanlar verileri silebilir. İnsanlar, yapmaması gereken verileri görebilir. İnsanlar, yazmaması gereken verileri yazabilir. Ve bu şeylerin çoğunu yalnızca bir şekilde batırırsanız ve kullanıcı girişini doğrulamazsanız yapabilirler.

Eval ile, pentagonu kesebilir ve senin yaptığın gibi gösterebilirler. Parolalarınızı almak için tuş vuruşlarınızı denetleyebilirler. Turing'in eksiksiz bir dili varsayarak, bilgisayarınızın yapabileceği her şeyi yapabilir.

Ve girişi doğrulayamazsınız. Bu keyfi bir serbest form dizesidir. Bunu doğrulamanın tek yolu, söz konusu dil için bir çözümleyici ve kod analiz motoru oluşturmaktır. Bol şans sana.


1
... veya bir oyunun yazım tanımlama dosyaları gibi girişin güvenilir bir kaynaktan gelmesini sağlayın.
user253751

3
@ immibis ancak giriş önceden tanımlanmış ve test edilmişse, sistem kaynağına dahil edilebildiğinde neden eval kullanmalısınız?
Jules

3
@ immibis - çünkü hiç kimse oyun dosyalarını
hacklemiyor

2
... “Turing complete” ne demek değildir (Turing eksiksizliği, gerçek dünyadaki bilgisayarla ilgisiz olmaktan bir adım ötededir).
Leushenko

1
@Telastyn: Bir Javascript programı yapamaz. Veya bir C ++ programı bile. Javascript, kendisi başka bir sanal alanda (x86'da ring 3) bulunan bir sanal alan (tarayıcı) içinde çalışır. Kesme vektörü, OS kontrolü altındaki bu sanal alanın dışında. Ve bu dış sanal alan, halka 3, CPU tarafından zorlanıyor.
MS’e

6

Bence şu yönlerden aşağı kayıyor:

  • zorunluluk
  • (Korumalı) Kullanımı
  • Erişim
  • doğrulanabilirliği
  • Çok aşamalı saldırılar

zorunluluk

Merhabalar, ben bu son derece harika resim düzenleme aracını yazdım ($ 0.02 için mevcut). Resmi açtıktan sonra, resminizin üzerine çok sayıda filtre aktarabilirsiniz. Python'u (uygulamayı yazdığım program) kullanarak kendiniz bile komut yazabilirsiniz. evalSaygıdeğer bir kullanıcı olduğun için sana güvenerek girişini kullanacağım .

(sonra)

Satın aldığın için teşekkürler. Gördüğünüz gibi tam olarak söz verdiğim gibi çalışıyor. Oh, resim açmak ister misin? Hayır yapamazsın. Bu readyöntemi biraz güvensiz olduğu için kullanmayacağım . Tasarruf? Hayır kullanmayacağım write.

Söylemeye çalıştığım şudur: Neredeyse temel araçlar için okuma / yazma gerekir. Ah-so-müthiş oyunun yüksek puanlarını saklamak için aynı.

Okuma / yazma olmadan, resim editörünüz işe yaramaz. Olmadan eval? Sana bunun için özel bir eklenti yazacağım!

(Korumalı) Kullanımı

Birçok yöntem potansiyel olarak tehlikeli olabilir. Mesela readve gibi write. Yaygın bir örnek, adını belirterek belirli bir dizinden görüntüleri okumanıza izin veren bir web servisidir. Bununla birlikte, 'isim' aslında sistemdeki herhangi bir geçerli (göreceli) yol olabilir, bu da sadece görüntüleri değil, web servisinin erişebildiği tüm dosyaları okumanızı sağlar. Bu basit örneğin kötüye kullanılması 'yol geçişi' olarak adlandırılır. Uygulamanız yol geçişine izin veriyorsa, kötüdür. Bir readyol geçişi için karşı savunmak olmadan kötülük çağrılabilir wel olabilir.

Ancak, diğer durumlarda, dize readtamamen programcıların kontrolü altındadır (belki kodlanmış?). Bu durumda, kullanmak çok kötü read.

Erişim

Şimdi, başka bir basit örnek kullanarak eval.

Web uygulamanızın bir yerinde, dinamik içerik istersiniz. Yöneticilerin çalıştırılabilir bir kod girmesine izin vereceksiniz. Yöneticilerin güvenilir kullanıcılar olduğunu görünce, bu teorik olarak iyi olabilir. Yönetici olmayanlar tarafından gönderilen kodları çalıştırmadığınızdan emin olun, sorun değil.

(Bu, o kadar güzel bir yönetici tarafından kovulana ve erişimini iptal etmeyi unuttuğuna kadar. Şimdi web uygulamanız çöktü).

Doğrulanabilirliği.

Önemli olan bir diğer yön, bence, kullanıcı girişini doğrulamanın ne kadar kolay olduğu.

Okuma girişinde kullanıcı girişi kullanılıyor mu? Sadece (çok) okuma araması girişinin zararlı hiçbir şey içermediğinden emin olun. Yolu normalleştirin ve açılan dosyanın medya dizininizde olduğunu doğrulayın. Şimdi bu güvenli.

Yazma çağrısında kullanıcı girişi? Aynı!

SQL enjeksiyonu? Sadece ondan kaçın ya da parametreli sorguları kullanın, güvendesiniz.

Eval? evalArama için kullanılan girişi nasıl doğrulayacaksınız ? Çok çalışabilirsiniz ama güvenli bir şekilde çalışması gerçekten çok zor (imkansız değilse).

Çok aşamalı saldırılar

Şimdi, kullanıcı girişini her kullanışınızda, kullanmanın yararlarını tehlikelere karşı tartmanız gerekir. Kullanımını mümkün olduğunca koruyun.

evalAdmin örneğindeki yetenekli maddeleri tekrar düşünün . Sana bunun iyi olduğunu söylemiştim.

Şimdi, web uygulamanızda, kullanıcı içeriğinden (HTML, XSS) kaçmayı unuttuğunuz bir yer olduğunu düşünün. Bu, kullanıcı tarafından erişilebilir değerlendirmeden daha küçük bir suçtur. Ancak, çıkmamış kullanıcı içeriğini kullanarak bir kullanıcı bir yöneticinin web tarayıcısını devralabilir evalve yöneticiler oturumu sırasında tekrar tam sistem erişimine izin veren bir blok ekleyebilir .

(Aynı çok aşamalı saldırı, XSS yerine SQL Injection ile yapılabilir veya bazı rastgele dosyalar kullanım yerine yürütülebilir kodun yerine yazılır eval)


2
“Çok sıkı çalışabilirsiniz, ancak güvenli bir şekilde çalışması gerçekten çok zor (imkansız değilse).” - O olduğunu imkansız. Basit kanıt: Sağlanan kodun "güvenli" olup olmadığını anlamaya çalışmak yerine, çok, daha basit bir şey bulmaya çalışın ve ne kadar zor olduğunu görün : deneyin , kullanıcı tarafından sağlanan kod durur mu?
Jörg W Mittag

2
@ JörgWMittag: Bana Coq ile yazılmış bir program verin ve ispatlayacağım.
André Paramés

1
@ JörgWMittag: Kabul edildi. Dile ve kullanıcı girişi kapsamına bağlı olarak. Olabilir eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). Girişin alfasayısal olduğunu doğrulamak mümkündür. Ayrıca, 'durur mu', 'dokunmaması gereken durumu değiştirir / erişir mi' ve 'aramaması gereken yöntemler yapar' için diktir.
Sjoerd Job Postmus,

3
@ JörgWMittag Belirli bir programın bir şey yapmayacağını kanıtlamak imkansızdır , ancak bunu kanıtlayabileceğiniz sınırlı bir dizi programın muhafazakar bir şekilde tanımlanması ve giriş programlarının bu grubun üyeleri olduğunu uygulamak imkansız değildir.
user253751

3

Bu özelliğin çalışabilmesi için, tüm programın iç durumuna tam erişim sağlayan bir yansıma katmanı tutmam gerektiği anlamına geliyor.

Tercüme edilmiş diller için basitçe tercüman durumunu kullanabilirim, bu kolay, ancak JIT derleyicileri ile birlikte karmaşıklığı önemli ölçüde artırıyor.

Olmadan eval, JIT derleyicisi sık sık bir iş parçacığının yerel verilerine başka bir koddan erişilmediğini ispatlayabilir, bu nedenle erişimleri yeniden sıralamak, kilitleri atlamak ve sık kullanılan verileri daha uzun süre önbelleğe almak tamamen kabul edilebilir. Başka bir iş parçacığı bir evalifade çalıştırdığında , çalışan JIT derlenmiş kodunu buna karşı senkronize etmek gerekebilir, bu nedenle aniden JIT'nin kodunun mantıklı bir zaman dilimi içinde en iyi duruma getirilmiş yürütmeye geri dönen bir geri dönüş mekanizmasına ihtiyacı vardır.

Bu tür bir kod çok ince, yeniden üretilmesi zor ve aynı zamanda JIT derleyicisine optimizasyon için bir sınır koyar.

Derlenmiş diller için takas daha da kötüdür: Çoğu optimizasyon yasaktır ve kapsamlı sembol bilgisini ve tercümanı çevrede tutmam gerekiyor, bu yüzden ek esneklik genellikle buna değmez - genellikle bazı dahili arayüzlere arayüz tanımlamak daha kolaydır. örneğin programın modeline bir komut dosyası görünümü ve denetleyici eşzamanlı erişim sağlayarak yapılar .


"Bu özelliğin çalışabilmesi için, tüm programın iç durumuna tam erişim sağlayan bir yansıma katmanını tutmam gerektiği anlamına geliyor" - hayır, sadece etkilemek istediğiniz parçalara. OpenERP / Odoo söz konusu olduğunda değerlendirilmekte olan kod yalnızca arayabileceği çok sınırlı sayıda değişkene ve işleve erişebilir ve hepsi iş parçacığı yereldir.
André Paramés

1

İşaretçi aritmetiğinden daha kötü veya doğrudan bellekten ve dosya sistemi erişiminden daha tehlikeli evalolarak kabul edilen önermeyi reddediyorum . Buna inanacak mantıklı bir geliştirici bilmiyorum. Ayrıca, işaretçi aritmetik / doğrudan bellek erişimini destekleyen diller tipik olarak desteklemez ve tam tersidir, bu yüzden böyle bir karşılaştırmanın ne kadar sıklıkla ilgili olacağından eminim.eval

Ancak , JavaScript tarafından desteklenmesi basit bir nedenden dolayı evaldaha iyi bilinen bir güvenlik açığı olabilir . JavaScript, doğrudan bellek veya dosya sistemi erişimi olmayan bir sanal alan dilidir, bu nedenle, dil uygulamasında kendi zayıflıklarını engelleyen bu güvenlik açıklarına sahip değildir. EvalBu nedenle, isteğe bağlı kod yürütme olasılığını açtığı için dilin en tehlikeli özelliklerinden biridir. JavaScript’te C / C ++ 'dan daha fazla sayıda geliştiricinin geliştiğine inanıyorum, bu yüzden evalgeliştiricilerin çoğunluğu için arabellek taşmalarından haberdar olmak çok daha önemli.


0

Hiçbir ciddi programcı, Eval'ın "Kötü" olduğunu düşünmez. Bu sadece diğerleri gibi bir programlama aracıdır. Bu işlevin korkusu (eğer bir korku varsa) popüler kültürle ilgisi yoktur. Bu, genellikle yanlış kullanılan, ciddi güvenlik delikleri getirebilen ve performansı düşürebilen tehlikeli bir komuttur. Kendi tecrübelerime göre, başka yollarla daha güvenli ve verimli bir şekilde çözülemeyen bir programlama problemiyle karşılaşmanın nadir olduğunu söyleyebilirim. Değerlendirmeyi kullanması en muhtemel olan programcılar, muhtemelen güvenli bir şekilde yapmak için en az nitelikli olanlardır.

Bunu söyledikten sonra, değerlendirmenin kullanımının uygun olduğu diller var. Perl akla geliyor. Bununla birlikte, kişisel olarak yapısal istisnaların ele alınmasını doğal olarak destekleyen diğer, daha modern dillerde çok nadiren gerekli olduğunu görüyorum.


bu, “Bu korkunun popüler kültürün bir parçası haline gelmesi için herhangi bir tarihsel gerçek var mı” sorusunu sormaya kalkışmaz. Bkz Cevap Nasıl
sivrisinek

Benim görüşüme göre soru sahte bir öncül dayanıyor, ben de böyle cevapladım.
user1751825

0

Bence sorunuzun daha sonraki bölümünde oldukça iyi anlaştınız (benimki vurguyla):

doğru kullanıldıkları sürece , iyi bir kullanımları vardır

Doğru kullanabilen% 95 için her şey yolunda ve güzel; ama her zaman onu düzgün kullanmayan insanlar olacaktır. Bunlardan bazıları deneyimsizliğe ve yeteneksizliğe bağlı olacak, geri kalanlar da kötü niyetli olacak.

Her zaman sınırları zorlamak ve güvenlik delikleri bulmak isteyen insanlar olacaktır - bazıları iyi, bazıları kötü.

Bunun tarihsel gerçeği yönü gelince, evaltip fonksiyonlar esas izin Keyfi kod yürütülmesine daha önce olmuştur popüler web CMS, Joomla sömürülen! . İle Joomla! Dünya çapında 2,5 milyondan fazla siteyi güçlendirmek , yalnızca bu sitelere gelen ziyaretçilere değil, barındırdığı altyapıya ve ayrıca sömürülen sitelerin / şirketlerin itibarına da büyük zarar verebilir.

Joomla! örnek basit bir örnek olabilir, ancak kaydedilen bir örnek.


0

Kullanımını caydırmak için bazı nedenler vardır eval(bazıları belirli dillere özgü olsa da).

  • Kullandığı çevre (sözcüksel ve dinamik olarak) evalsıklıkla şaşırtıcıdır (yani, eval(something here)bir şeyi yapması gerektiğini düşünüyorsunuz , ancak başka bir şey yapar, muhtemelen istisnaları tetikler)
  • Sık sık aynı şeyi başarmanın daha iyi bir yolu vardır (inşa edilmiş sözcük kapanmalarının birleştirilmesi bazen daha iyi bir çözümdür, ancak bu Ortak Lisp'a özgü olabilir)
  • Güvenli olmayan verilerin değerlendirilmesine son vermek çok kolaydır (bununla birlikte çoğunlukla korunabilir).

Ben şahsen, bunun kötü olduğunu söylemeye kadar gitmezdim, ama her zaman evalbir kod incelemesinde kullanımına her zaman meydan okuyacağım, " burada bazı kodlar düşündünüz mü?" (en azından geçici bir değişiklik yapmak için zamanım varsa) veya "bir değerlendirmenin gerçekten en iyi çözüm olduğundan emin misiniz?" (eğer yapmazsam).


bu, “Bu korkunun popüler kültürün bir parçası haline gelmesi için herhangi bir tarihsel gerçek var mı” sorusunu sormaya kalkışmaz. Bkz Cevap Nasıl
sivrisinek

0

Minsky'nin Zihin Derneği’nde Bölüm 6.4’te

Bir aklın kendisini izlemesinin ve hala olanları izlemesinin bir yolu vardır . Beyni iki bölüme ayırın, A ve B A-beyninin giriş ve çıkışlarını gerçek dünyaya bağlayın - orada ne olduğunu algılayabilir. Fakat B-beynini dış dünyaya bağlamayın; bunun yerine A beyni B beyinin dünyası olacak şekilde bağlayın!

Bir program (B) başka bir program (A) yazdığında, bir meta program olarak işlev görür. B'nin konusu A programı.

Bir C programı var. İçerdeydi biri sizin programı B. yazıyor kafasına

Tehlike, kötü niyetli, bu sürece müdahale edebilecek biri (C ') olabilir, bu yüzden SQL-Injection gibi şeyler elde edersiniz.

Buradaki zorluk, yazılımı daha tehlikeli hale getirmeden daha akıllı hale getirmektir.


İki ve iki aşağı oy. Görünüşe göre bu belki bir sinire çarpıyor
Mike Dunlavey

0

Burada çok sayıda iyi cevabınız var ve asıl sebep açıkça rastgele kod çalıştırma işleminin kötü mmmkay olması, ancak başkalarının sadece kendilerine değdikleri diğer bir faktör daha ekleyeceğim:

Öyle gerçekten bir metin dizesi dışına değerlendirilmektedir koduyla ilgili sorunları gidermek zor. Normal hata ayıklama araçlarınız pencerenin hemen dışına çıkar ve çok eski okulların izini sürmeye veya yankıya düşersiniz. Açıkçası, istediğiniz tek bir astarda bir parçanız varsa, bunun kadar önemli değil, evalancak deneyimli bir programcı olarak muhtemelen bunun için daha iyi bir çözüm bulabilirsiniz, oysa daha büyük ölçekli kod üretimi bir değerlendirme işlevinin olabileceği bir yerde olabilir. potansiyel olarak yararlı bir müttefik olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.