日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案

發布時間:2025/3/19 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近一個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]}

將格式化作沙箱化處理

那么,如果需要讓其他人提供格式化字符串,那該怎么辦呢? 其實,可以利用某些未公開的內部機制來改變字符串格式化行為。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()

{C}

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:

obj?=?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格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。