go预防跨站脚本
現(xiàn)在的網(wǎng)站包含大量的動(dòng)態(tài)內(nèi)容以提高用戶體驗(yàn),比過(guò)去要復(fù)雜得多。所謂動(dòng)態(tài)內(nèi)容,就是根據(jù)用戶環(huán)境和需要,Web應(yīng)用程序能夠輸出相應(yīng)的內(nèi)容。動(dòng)態(tài)站點(diǎn)會(huì)受到一種名為“跨站腳本攻擊”(Cross Site Scripting, 安全專家們通常將其縮寫成 XSS)的威脅,而靜態(tài)站點(diǎn)則完全不受其影響。
攻擊者通常會(huì)在有漏洞的程序中插入JavaScript、VBScript、 ActiveX或Flash以欺騙用戶。一旦得手,他們可以盜取用戶帳戶信息,修改用戶設(shè)置,盜取/污染cookie和植入惡意廣告等。
對(duì)XSS最佳的防護(hù)應(yīng)該結(jié)合以下兩種方法:一是驗(yàn)證所有輸入數(shù)據(jù),有效檢測(cè)攻擊(這個(gè)我們前面小節(jié)已經(jīng)有過(guò)介紹);另一個(gè)是對(duì)所有輸出數(shù)據(jù)進(jìn)行適當(dāng)?shù)奶幚?#xff0c;以防止任何已成功注入的腳本在瀏覽器端運(yùn)行。
那么Go里面是怎么做這個(gè)有效防護(hù)的呢?Go的html/template里面帶有下面幾個(gè)函數(shù)可以幫你轉(zhuǎn)義
- func HTMLEscape(w io.Writer, b []byte) //把b進(jìn)行轉(zhuǎn)義之后寫到w
- func HTMLEscapeString(s string) string //轉(zhuǎn)義s之后返回結(jié)果字符串
- func HTMLEscaper(args ...interface{}) string //支持多個(gè)參數(shù)一起轉(zhuǎn)義,返回結(jié)果字符串
我們看4.1小節(jié)的例子
fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) //輸出到服務(wù)器端 fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password"))) template.HTMLEscape(w, []byte(r.Form.Get("username"))) //輸出到客戶端?
Go的html/template包默認(rèn)幫你過(guò)濾了html標(biāo)簽,但是有時(shí)候你只想要輸出這個(gè)alert()看起來(lái)正常的信息,該怎么處理?請(qǐng)使用text/template。請(qǐng)看下面的例子:
import "text/template" ... t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")輸出
Hello, <script>alert('you have been pwned')</script>!或者使用template.HTML類型
import "html/template" ... t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) err = t.ExecuteTemplate(out, "T", template.HTML("<script>alert('you have been pwned')</script>"))輸出
Hello, <script>alert('you have been pwned')</script>!轉(zhuǎn)換成template.HTML后,變量的內(nèi)容也不會(huì)被轉(zhuǎn)義
轉(zhuǎn)義的例子:
import "html/template" ... t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")轉(zhuǎn)義之后的輸出:
Hello, <script>alert('you have been pwned')</script>!總結(jié)
- 上一篇: go验证表单的输入
- 下一篇: go中的database/sql接口