本文給大家主要講述的是Python 模板引擎的注入問題分析,以及如何防範和需要注意的地方,有需要的小伙伴可以參考下
這幾年比較火的一個漏洞就是jinjia2之類的模板引擎的注入,透過注入模板引擎的一些特定的指令格式,例如{{1+1}} 而返回了2 得知漏洞存在。實際類似的問題在Python原生字串中就存在,尤其是Python 3.6新增 f 字串後,雖然利用還不明確,但應該要注意。
最原始的 %
userdata = {"user" : "jdoe", "password" : "secret" } passwd = raw_input("Password: ") if passwd != userdata["password"]: print ("Password " + passwd + " is wrong for user %(user)s") % userdata
如果用戶輸入 %(password)s 那就可以取得使用者的真實密碼了。
format方法相關
https://docs.python.org/3/library/functions.html#format
除了上面的payload改寫為print ("" + wrong + " isPasswords user {user}").format(**userdata) 之外,還可以
>>> import os >>> '{0.system}'.format(os) '<built-in function system>'
會先把0 替換為format 中的參數,然後繼續取得相關的屬性。
但是看似只能取得屬性,不能執行方法?但是也可以獲得一些敏感資訊了。
範例: http://www.php.cn/
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]} 就可以洩漏敏感資訊。
Python 3.6中的 f 字串
這個字串非常厲害,和Javascript ES6中的範本字串類似,有了取得當前context下變數的能力。
https://docs.python.org/3/reference/lexical_analysis.html#f-strings
>>> a = "Hello" >>> b = f"{a} World" >>> b 'Hello World'
而且不僅限制為屬性了,程式碼可以執行了。
>>> import os >>> f"{os.system('ls')}" bin etc lib media proc run srv tmp var dev home linuxrc mnt root sbin sys usr '0' >>> f"{(lambda x: x - 10)(100)}" '90'
但是貌似 沒有 把一個普通字串轉換為 f 字串的方法,也就是說使用者很可能無法控制一個 f 字串,可能無法利用,還需要繼續查一下。
更多Python 模板引擎的注入問題分析相關文章請關注PHP中文網!