Python程式猿必知的新型字串格式漏洞

來源:互聯網
上載者:User

標籤:

本文對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(eventevent=event)

如果使用者可以在這裡注入format_string,那麼他們就能發現下面這樣的秘密字串:

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

將格式化作沙箱化處理

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

from string import Formatter

from collections import Mapping

class MagicFormatMapping(Mapping):

"""This class implements a dummy wrapper to fix a bug in the Python

standard library for string formatting.

See http://bugs.python.org/issue13598 for information about why

this is necessary.

"""

def __init__(self, args, kwargs):

self._args = args

self._kwargs = kwargs

self._last_index = 0

def __getitem__(self, key):

if key == ’’:

idx = self._last_index

self._last_index += 1

try:

return self._args[idx]

except LookupError:

pass

key = str(idx)

return self._kwargs[key]

def __iter__(self):

return iter(self._kwargs)

def __len__(self):

return len(self._kwargs)

# This is a necessary API but it’s undocumented and moved around

# between Python releases

try:

from _string import formatter_field_name_split

except ImportError:

formatter_field_name_split = lambda

x: x._formatter_field_name_split()

class SafeFormatter(Formatter):

def get_field(self, field_name, args, kwargs):

first, rest = formatter_field_name_split(field_name)

obj = self.get_value(first, args, kwargs)

for is_attr, i in rest:

if is_attr:

obj = safe_getattr(obj, i)

else:

objobj = obj[i]

return obj, first

def safe_getattr(obj, attr):

# Expand the logic here. For instance on 2.x you will also need

# to disallow func_globals, on 3.x you will also need to hide

# things like cr_frame and others. So ideally have a list of

# objects that are entirely unsafe to access.

if attr[:1] == ’_’:

raise AttributeError(attr)

return getattr(obj, attr)

def safe_format(_string, *args, **kwargs):

formatter = SafeFormatter()

kwargs = MagicFormatMapping(args, kwargs)

return formatter.vformat(_string, args, kwargs)

現在,我們就可以使用safe_format方法來替代str.format了:

>>> ’{0.__class__}’.format(42)

""

>>> safe_format(’{0.__class__}’, 42)

Traceback (most recent call last):

File "", line 1, in

AttributeError: __class__

小結

在本文中,我們對Python引入的一種格式化字串的新型文法的安全性漏洞進行了深入的分析,並提供了相應的安全解決方案,希望對讀者能夠有所協助。

 

來源:51CTO

Python程式猿必知的新型字串格式漏洞

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.