2010-01-03 93 views
3

我正在建立一個網站,我有一個需要,用戶應該能夠評估一些表達式基於數據庫表中的值,而不是使用像pyparsing等工具,我正在考慮使用python本身,並且已經想出了一個足以達到我的目的的解決方案。我基本上使用eval來評估表達式並傳遞全局空字符__builtins__,這樣就不會有任何東西可以被訪問,並且當地人從DB中得到值,如果用戶需要某些函數,我也可以通過這些函數。使用eval進行表達式評估安全性如何?

import datetime 
def today(): 
    return datetime.datetime.now() 

expression = """ first_name.lower() == "anurag" and today().year == 2010 """ 

print eval(expression, {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 

所以我的問題是,如何安全是,我有三個標準

  1. 我的程序或表格等someshow的用戶訪問當前的狀態可以嗎?
  2. 用戶可以訪問os級別的調用嗎?
  3. 用戶可以通過循環或使用大量內存來暫停我的系統,例如通過做範圍(10 * 8),在某些情況下,他可以例如100 ** 1000等等,所以3不是一個問題。我可以使用標記來檢查這樣的操作,無論如何,我將使用GAE,所以它不是很關心。

編輯:IMO這不是Q:661084重複的,因爲在那裏結束這一個開始,我想知道,即使__builtins__堵塞,用戶可以做壞事?

+0

檢查:http:// stackoverflow。com/questions/661084/pythons -eval-on-untrusted-strings – fserb 2010-01-03 05:36:19

+0

@fserb查看編輯 – 2010-01-03 05:40:59

回答

7

它是完全不安全使用eval,甚至內置插件清空受阻 - 攻擊者可以用文字開始,得到它的__class__,等,等,多達object,其__subclasses__,等等...基本上,Python內省太強大,無法站立給一個熟練的,堅定的攻擊者。

ast.literal_eval安全的,如果你可以通過它的侷限性住...

+1

好吧我相信你:)但一些反例將是有趣的,無論如何,我會嘗試PyParsing然後。 – 2010-01-03 06:49:11

+1

你可以到任何*類型或類(通過'__class__'和'__mro__'或'__bases__',然後通過'__subclasses__'向下移動到'object')的提示應該是足夠的作爲「反例」:讓想要發揮破壞性惡作劇的惡意黑客至少花一分鐘時間構建解決方案......!) – 2010-01-03 16:39:19

4

當然,即使沒有內置函數,也可能消耗所有可用內存或創建無限循環。有很多方法可以做到這一點,如「A」 * 999999 * 999999,或使一個無限循環:

>>> print eval('[[x.append(a) for a in x] for x in [[0]]]', 
...    {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 

至於1)和2),我不知道,但它看起來有風險的。這裏有一兩件事,我想,我想會的工作,但它似乎已被其他人認爲攻擊該行並阻止它:

>>> import datetime 
>>> def today(): 
>>>  return datetime.datetime.now() 
>>> 
>>> print eval('today.func_globals', {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 
RuntimeError: restricted attribute 

我一半期望得到這個代替:

{'__builtins__': <module '__builtin__' (built-in)>, ... 

所以我認爲這可能是一個壞主意。你只需要一個小孔,你可以訪問整個系統。你有沒有考慮過其他不使用eval的方法?他們怎麼了?

+0

是設置__builtins__變量,限制執行模式踢入:) – 2010-01-03 05:52:04

+0

+1對'restricted attribute'我不知道看起來像是由於舊的reexec模塊,我想使用eval,因爲如果我可以爲什麼不呢? – 2010-01-03 05:59:19

2

它有可能獲得創建和調用的程序,其中包括那些可以退出Python解釋器中定義的任何類。另外,你可以創建並執行任意字節碼字符串,這可以對解釋器進行段錯誤。所有的細節見Eval really is dangerous