2008-08-19 90 views
51

清理基於Python的Web應用程序的用戶輸入的最佳方式是什麼?是否有單一功能來刪除HTML字符和任何其他必要的字符組合以防止發生XSS或SQL注入攻擊?使用Python清理用戶輸入

+9

你不應該試圖通過消毒來解決SQL注入用戶輸入!如果數據庫API正確使用,則不會有SQL注入的機會。 – 2010-03-22 20:52:57

+2

`...如果使用數據庫API恰當的是沒有SQL注入的機會。正確地說,你的意思是使用參數化查詢嗎?這是否覆蓋你100%? – Medorator 2014-08-27 15:03:36

+2

@buffer,我知道你的評論是舊的,但如果你想讓除OP之外的其他人看到你的評論,你必須用\ @符號將它們打出來。 – user1717828 2015-10-27 19:59:07

回答

0

如果您使用像django這樣的框架,該框架可以輕鬆地爲您使用標準過濾器執行此操作。事實上,我很確定django會自動執行它,除非您告訴它不要。

否則,我會建議在接受來自表單的輸入之前使用某種正則表達式驗證。我不認爲你的問題有一個銀彈,但使用重新模塊,你應該能夠構建你所需要的。

6

傑夫阿特伍德自己形容StackOverflow.com如何進行消毒的堆棧溢出博客用戶輸入(在非語言的具體條款):http://blog.stackoverflow.com/2008/06/safe-html-and-xss/

然而,賈斯汀指出,如果你使用Django模板或類似的東西那麼他們可能會淨化你的HTML輸出。

SQL注入也不應該是一個問題。所有Python的數據庫庫(MySQLdb,cx_Oracle等)都會清理你傳遞的參數。 Python的所有對象關係映射器(如Django模型)都使用這些庫,因此您不必擔心那裏的衛生設施。

24

這是一個片段,它將刪除所有不在白名單上的標籤,並且所有標籤屬性都不在白名單上(因此您不能使用onclick)。

這是http://www.djangosnippets.org/snippets/205/的改良版,與http://ha.ckers.org/xss.html描述的屬性值的正則表達式,以防止有人利用href="javascript:...",和其他案件。
(例如<a href="ja&#x09;vascript:alert('hi')"><a href="ja vascript:alert('hi')">等)

正如你所看到的,它使用的(真棒)BeautifulSoup庫。

import re 
from urlparse import urljoin 
from BeautifulSoup import BeautifulSoup, Comment 

def sanitizeHtml(value, base_url=None): 
    rjs = r'[\s]*(&#x.{1,7})?'.join(list('javascript:')) 
    rvb = r'[\s]*(&#x.{1,7})?'.join(list('vbscript:')) 
    re_scripts = re.compile('(%s)|(%s)' % (rjs, rvb), re.IGNORECASE) 
    validTags = 'p i strong b u a h1 h2 h3 pre br img'.split() 
    validAttrs = 'href src width height'.split() 
    urlAttrs = 'href src'.split() # Attributes which should have a URL 
    soup = BeautifulSoup(value) 
    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)): 
     # Get rid of comments 
     comment.extract() 
    for tag in soup.findAll(True): 
     if tag.name not in validTags: 
      tag.hidden = True 
     attrs = tag.attrs 
     tag.attrs = [] 
     for attr, val in attrs: 
      if attr in validAttrs: 
       val = re_scripts.sub('', val) # Remove scripts (vbs & js) 
       if attr in urlAttrs: 
        val = urljoin(base_url, val) # Calculate the absolute url 
       tag.attrs.append((attr, val)) 

    return soup.renderContents().decode('utf8') 

至於其他的海報說,幾乎所有的Python DB庫照顧SQL注入的,所以這應該非常蓋你。

+2

我提高了這一點,但現在我不太確定。我不認爲這可以保護IE用戶免受src =「vbscript:msgbox('xss')」的攻擊。 – 2010-03-22 18:30:06

4

我不這樣做Web開發多不再,但是當我做,我做了一件像這樣:

當沒有解析是應該發生的,我通常只是逃避數據不與數據庫干擾當我存儲它,並逃離從數據庫中讀取的所有內容,以便在顯示它時不干擾html(在python中使用cgi.escape())。

有可能是,如果有人試圖輸入html字符或東西,他們實際上希望它被顯示爲文本。如果他們沒有,好睏難:)

總之逃避什麼會影響當前目標的數據。

當我確實需要一些解析(標記或其他)時,我通常試圖用html保持該語言不交叉集合,所以我仍然可以適當地將它存儲(在驗證語法錯誤後)並解析它HTML時顯示,而不必擔心用戶放在那裏干擾你的HTML數據。

Escaping HTML

12

見防止XSS不是要設法和過濾一切的最好方式,而是簡單地做HTML實體編碼。例如,自動將<轉換爲& lt ;.這是理想的解決方案,假設您不需要接受任何html輸入(在用作標記的論壇/評論區域之外,需要接受HTML應該很少見)。通過替代編碼有如此多的排列,除了超限制的白名單(例如a-z,A-Z,0-9)之外的任何東西都會讓某些東西通過。

如果您只是構建查詢字符串,則與其他意見相反,SQL注入仍是可能的。例如,如果您只是將傳入參數連接到查詢字符串,則您將擁有SQL注入。防止出現這種情況的最好方法也不是過濾,而是虔誠地使用參數化查詢,而不是連接用戶輸入。

這並不是說過濾仍不是最佳實踐,但就SQL注入和XSS而言,如果您宗教上使用參數化查詢和HTML實體編碼,將會受到更多的保護。

19

編輯bleach是html5lib的一個包裝,使它更容易用作基於白名單的sanitiser。

html5lib附帶基於白名單的HTML sanitiser - 很容易將其子類化,以限制用戶可以在您的網站上使用的標籤和屬性,甚至可以嘗試清理CSS,如果您允許使用style屬性。

這裏的現在,我使用它在我堆棧溢出的克隆的sanitize_html效用函數:

http://code.google.com/p/soclone/source/browse/trunk/soclone/utils/html.py

我已經拋出(在ha.ckers.org's XSS Cheatsheet列出的所有攻擊,這是在執行降價後的它輕而易舉地available in XML format HTML轉換使用python-markdown2並且它似乎保持不變

雖然Stackoverflow當前使用的WMD編輯器組件是一個問題,但實際上我不得不禁用JavaScript來測試XS S Cheatsheet攻擊將它們全部粘貼到WMD中,最終給了我警戒框並清空了頁面。

2

要清理要存儲到數據庫的字符串輸入(例如客戶名稱),您需要將其轉義或明顯地從中刪除引號(',「)。如果你正在組裝從用戶傳遞的字符串的SQL查詢可以發生

例如(如果它是可以接受的完全刪除引號):

datasetName = datasetName.replace("'","").replace('"',"")