FavoriteLoading
0

Python新型字符串格式漏洞分析

本文對Python引入的一種格式化字符串的新型語法的安全漏洞進行了深入的分析,并提供了相應的安全解決方案。
當我們對不可信的用戶輸入使用str.format的時候,將會帶來安全隱患——對于這個問題,其實我早就知道了,但是直到今天我才真正意識到它的嚴重性。因為攻擊者可以利用它來繞過Jinja2沙盒,這會造成嚴重的信息泄露問題。同時,我在本文最后部分為str.format提供了一個新的安全版本。
需要提醒的是,這是一個相當嚴重的安全隱患,這里之所以撰文介紹,是因為大多數人很可能不知道它是多么容易被利用。
核心問題
從Python 2.6開始,Python受.NET啟發而引入了一種格式化字符串的新型語法。當然,除了Python之外,Rust及其他一些編程語言也支持這種語法。借助于.format()方法,該語法可以應用到字節和unicode字符串(在Python 3中,只能用于unicode字符串)上面,此外,它還能映射為更加具有可定制性的string.Formatter API。
該語法的一個特點是,人們可以通過它確定出字符串格式的位置和關鍵字參數,并且隨時可以顯式對數據項重新排序。此外,它甚至可以訪問對象的屬性和數據項——這是導致這里的安全問題的根本原因。
總的來說,人們可以利用它來進行以下事情:

>>> 'class of {0} is {0.__class__}'.format(42)
"class of 42 is "

實質上,任何能夠控制格式字符串的人都有可能訪問對象的各種內部屬性。
問題出在哪里?
第一個問題是,如何控制格式字符串。可以從下列地方下手:
1.字符串文件中不可信的翻譯器。我們很可能通過它們得手,因為許多被翻譯成多種語言的應用程序都會用到這種新式Python字符串格式化方法,但是并非所有人都會對輸入的所有字符串進行全面的審查。
2.用戶暴露的配置。 由于一些系統用戶可以對某些行為進行配置,而這些配置有可能以格式字符串的形式被暴露出來。需要特別提示的是,我就見過某些用戶可以通過Web應用程序來配置通知郵件、日志消息格式或其他基本模板。

危險等級
如果只是向該格式字符串傳遞C解釋器對象的話,倒是不會有太大的危險,因為這樣的話,你最多會暴露一些整數類之類的東西。
然而,一旦Python對象被傳遞給這種格式字符串的話,那就麻煩了。這是因為,能夠從Python函數暴露的東西的數量是相當驚人的。 下面是假想的Web應用程序的情形,這種情況下能夠泄露密鑰:

CONFIG = {
    'SECRET_KEY': 'super secret key'
}
  
class Event(object):
    def __init__(self, id, level, message):
        self.id = id
        self.level = level
        self.message = message
  
def format_event(format_string, event):
    return format_string.format(event=event)

如果用戶可以在這里注入format_string,那么他們就能發現下面這樣的秘密字符串:

{event.__init__.__globals__[CONFIG][SECRET_KEY]}

將格式化作沙箱化處理
那么,如果需要讓其他人提供格式化字符串,那該怎么辦呢? 其實,可以利用某些未公開的內部機制來改變字符串格式化行為。

分頁閱讀: 1 2
【聲明】:8090安全小組門戶(http://www.jvwkvg.tw)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。