Güvenilmeyen kodların yürütülmesi için en iyi yöntemler


31

Kullanıcıların sunucuma karşı rasgele, güvenilmeyen python kodu ( bunun gibi ) çalıştırmasına izin vermem gereken bir projem var . Python için oldukça yeniyim ve sisteme güvenlik delikleri veya diğer güvenlik açıkları getirecek herhangi bir hata yapmaktan kaçınmak istiyorum. Hizmetimi kullanılabilir hale getirmek için kullanabileceğim, kötüye kullanılamaz hale getirebileceğim en iyi yöntemler, önerilen okumalar veya diğer işaretçiler var mı?

İşte şimdiye kadar düşündüklerim:

  • Gibi potansiyel olarak tehlikeli paketlerin kullanımını yasaklamak __builtins__için execbağlamdan çıkarın os. Kullanıcılar yalnızca kendilerine sunduğum paketleri kullanabilecekler.
  • Makul bir zaman aşımını zorlamak için konuları kullanın.
  • execBağlam içinde ayrılabilecek toplam hafıza miktarını sınırlamak istiyorum , ancak mümkün olup olmadığından emin değilim.

Bir düz için bazı alternatifler var exec, ancak bunlardan hangisinin burada yardımcı olacağından emin değilim:

  • ast.NodeVisitorGüvenli olmayan nesnelere erişmek için herhangi bir girişimi yakalamak için Using kullanın. Ama hangi nesneleri yasaklamalıyım?
  • Girişte herhangi bir çift alt çizgi aranıyor. (yukarıdaki seçenekten daha az zarif).
  • Kullanma PyPyveya kodu sandbox'a benzer bir şey kullanmak .

NOT: En az bir JavaScript tabanlı tercüman olduğunu biliyorum . Bu benim senaryomda işe yaramayacak.



3
@ MartijnPieters: Mükemmel. Her birini özetlerseniz, muhtemelen bir cevaba layıktır.
Robert Harvey,

Ayrıca şunları göz önünde bulundurun: diskte kalan çöp, ağ (spam veya herhangi bir şekilde göndermelerine izin verme), diğer dosyalara izin verme (dosyalarınızı okuma). Döngü bile olsa CD mekaniklerini imha edebiliyorsa ... Sanallaştırma (buna adlandıracağınız hapishaneler veya kvm) ya da en azından neredeyse hiçbir imtiyazı olmayan kullanıcılar için giderdim. Kendi programlarınızı geliştirmek için makul düzeyde bir hafıza ve hafıza miktarını ayarlayın.
kyticka


1
PyPy'yi deneyin :> Sandboxing: PyPy, güvenilmeyen kodu tamamen güvenli bir şekilde çalıştırma olanağı sağlar.
Vorac

Yanıtlar:


28

Python sanallaştırma zordur . Python doğası gereği, birden çok düzeyde iç içe geçmiş durumda.

Bu ayrıca, belirli tipler için fabrika yöntemlerini bu türlerin kendisinden bulabileceğiniz ve tercüman tarafından sınırlama olmaksızın doğrudan çalıştırılacak yeni düşük seviyeli nesneler oluşturabileceğiniz anlamına gelir.

Python sanal alanlarından kurtulmanın yaratıcı yollarını bulma örnekleri:

Temel fikir her zaman temel Python türlerini oluşturmanın bir yolunu bulmaktır; Fonksiyonlar ve sınıflar ve Python yorumlayıcısının keyfi (denetlenmeyen!) bytecode komutunu çalıştırmasını sağlayarak kabuğun kırılmasını sağlar.

Aynı ve daha fazlası execifade için de geçerlidir ( exec()Python 3'teki işlev).

Demek istediğin:

  • Python kodunun bayt derlemesini kesinlikle denetleyin veya en azından alt çizgi ile başlayan adlara erişimi kaldırmak için bayt kodunu işleyin.

    Bu, Python yorumlayıcısının nasıl çalıştığı ve Python bayt kodunun nasıl yapılandırıldığı hakkında kesin bilgi gerektirir. Kod nesneleri iç içe geçmiş; Bir modülün bayt kodu sadece üst düzey ifadeleri kapsar, her bir fonksiyon ve sınıf iç içe geçmiş fonksiyonlar ve sınıflar için diğer bytecode nesnelerini içeren kendi bytecode sekansı artı meta verileri içerir .

  • Kullanılabilecek modülleri beyaz listeye eklemeniz gerekir . Dikkatle.

    Bir python modülü diğer modüllere referanslar içerir . İçe aktarırsanız os, osmodül ad alanınızda modüle başvuran yerel bir ad vardır os. Bu, kararlı bir saldırganın sanal alandan çıkmalarına yardımcı olabilecek modüllere yol açabilir. pickleModül, örneğin, eğer öyleyse, örneğin keyfi kod nesneleri yüklemek sağlayan herhangi aklisteli modülleri kablo ile yol picklemodülü, hala bir sorun var.

  • Zaman kotalarını kesinlikle sınırlamanız gerekir. En kısırlaştırılmış kod bile, kaynaklarınızı bağlayarak hala sonsuza dek çalışmayı deneyebilir.

Size katı bayt kodu kontrolü vermeye çalışan RestrictedPython'a bir bakın . RestrictedPythonPython kodunu, Python 2.3 ile 2.7 arasında hangi adlara, modüllere ve nesnelere izin verildiğini kontrol etmenizi sağlayan bir şeye dönüştürür.

RestrictedPythonAmaçlarınız için yeterince güvenli ise , uyguladığınız politikalara bağlıdır. Alt çizgi ile başlayan ve modüllerin kesin olarak beyaz listeye alınmasına izin vermemek bir başlangıç ​​olacaktır.

Bence, gerçekten sağlam olan tek seçenek, her çalıştırmadan sonra yok ettiğiniz dış dünyaya ağ erişimi olmayan ayrı bir Sanal Makine kullanmak. Her yeni betiğe bunun yerine yeni bir VM verilir. Bu şekilde, kod Python sanal alanınızdan (ki pek de muhtemel olmayan) ayrılmayı başlasa bile, tüm saldırganın erişim hakkı kısa sürelidir ve değeri yoktur.


10

TL; DR Bir chroot / hapishane kullanın ve herhangi bir imtiyaz olmadan özel bir kullanıcı olarak çalıştırın.

Güvenilmeyen kodu çalıştırmak için en iyi yöntem, onu bir sistem sanal alanı aracılığıyla ayırmaktır. En fazla güvenlik için:

  • Sadece Python ile bağımlılıklarını ve konteynerin bağımlılıklarını içeren bir konteyner yarat
  • Kesinlikle gerekli olmayan tüm cihazlar olmadan bir konteyner oluşturmak (ör. ağ ve depolama)
  • bellek ve işlem kullanımı ile ilgili kısıtlamaları olan bir kap oluşturmak
  • kabı her çalıştırmada yeniden yaratın (ya da en azından her bir benzersiz kullanıcı ve en uzun süre ile
  • gerekli olan en düşük ayrıcalığa sahip bir kullanıcı olarak çalıştırmak
  • dosya yazma iznine sahip olmayan bir kullanıcı olarak çalıştırma

Ayrıca, chroot'ta güvenli bir şekilde çalışmak için standart uygulamaları da izleyin. Her çağrıda chroot'un dosya sistemini yeniden oluşturabilirsiniz, ayrıca özellikle paranoyak. Genelde, kullanıcının chroot'un içinde çalıştığı dosya sisteminde değişiklikler yapamamasını sağlarsınız.


Bu, uzaktan bile doğru olduğundan emin olacağınız tek şey - kendi sürecini verin.
Michael Kohne

3

Bunu güvenle yapabilmenin imkanı yok.

Böyle bir şeyi güvenli bir şekilde yapmak istiyorsanız, tamamen kontrollü bir ortamda çalışan, tercihen sisteminiz yerine kullanıcıların tarayıcısında çalışan kendi python uygulamanıza sahip olmakla başlamanız gerekir. Jython (java için python) ile başlayabilir ve bir java uygulaması olarak paketleyebilirsiniz. Java sanal alanında, kullanıcının makinesinde çalışacağından, sisteminiz makul derecede güvenli olacaktır.


4
Güvenlik sorunu, müşterisinin makinesi için değil sunucusununki içindi. Java'nın, diğer tüm web teknolojilerinde olduğu gibi, potansiyel güvenlik tehlikeleri, sunucunun istemciye tehlikeli programları dağıtmak için kullanılabildiğidir.
ddyer

1
@grasGendarme, uçak kazalarına dair yeni fırtınalar gibi size gerçekte ne kadar nadir olduğu hakkında çok şey söylüyor; Java güvenlik delikleriyle ilgili hikayeler Java'nın nispeten güvenli olduğunu söylüyor. C hakkında asla böyle bir hikaye elde edemezsiniz çünkü elde edeceğiniz yanıt "iyi olur; eğer onu çalıştırırsanız ne isterse yapar"
Richard Tingle,

2

Martijn'in yukarıda söylediği gibi, Python'da bu gerçekten çok zor. Açıkça söylendiği gibi, Python çok iç içe olduğu için, dil özelliklerini kısıtlayarak bunun mümkün olduğunu sanmıyorum. Bir Python sürümü için çalışan bir sanal alan elde ederseniz, bir sonraki sürümün bunu kırabileceği ihtimali vardır.

Standart CPython yerine PyPy'ye bir göz atardım . Kısacası, Python'un uyumlu bir alternatif uygulamasıdır. Çeşitli avantajları ve farklı özellikleri vardır ve bunlardan biri, dil özelliklerini sınırlamak yerine sistem çağrılarını değiştirerek sanal alandır.


0

Performans sizin için çok önemli olmadığı sürece, onu her zaman JavaScript sanal alanına koyan Brython'da çalıştırabilirsiniz.

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.