上一节我们讲了常用输入的验证,接下来我们看看关于安全方面的验证,怎么预防和验证的。
现在的Web(网站等)应用程序包含大量的动态内容来提高用户体验,比过去复杂很多,动态站点会收到来自各自安全方面的考验,其中一种叫做跨脚本攻击(Cross Site Scripting 简称:XSS),攻击者通常会在程序中插入Javascript、VBScript、Active或Flash以欺骗用户。一旦成功,他们可以盗取用户信息,修改用户设置,盗取相应信息。
对XSS上一节我们介绍了一种验证所有输入数据,有效检测攻击;另外是对所有数据进行适当的处理,以防止任何已成功注入的脚本在浏览器端运行。
Go语言中利用html/template中的几个函数帮我们转义。
func HTMLEscape(wio.writer,b [] byte) //把b进行转义之后写到w
funcHTMLEscapeString( s string) string //转义s之后返回结果字符串
func HTMLEscaper(args…interface{})string//支持多个参数一起转义,返回结果字符串。
例子1:
fmt.Println(“name:”,template.HTMLEscapeString(r.Form.Get(“name”)))//输出到服务端-姓名
fmt.Println(“passwor:”,template.HTMLEscapeString(r.Form.Get(“password”)))//输出到服务端-密码
template.HTMLEscape(w,[]byte(r.Form.Get(“name”)))//输出到客户端
如果我们在姓名输入框中输入的内容为alert(),我们可以在浏览器上面看看输出结果是?<script>alert()</script>这是Javascript过滤之后的输出,如果我们需要显示未过滤的的信息呢?
例子2:
import “text/template”
t,err:=template.New(“foo”).Parse(‘{{define “T”}} Hello,{{.}}{{end}}’)
err= t.ExecuteTemplate(out,”T”,”<script>alert(‘Haodo you do?’)</script>”)
输出:Hello,alert(‘Hao do you do?’)
也可以使用template.HTML类型:
例子3:
import “text/template”
t,err:=template.New(“foo”).Parse(‘{{define “T”}} Hello,{{.}}{{end}}’)
err= t.ExecuteTemplate(out,”T”,template.HTML(”<script>alert(‘Haodo you do?’)</script>”))
输出:Hello,alert(‘Hao do you do?’)
下面我们看看Go语言中怎么防止重复提交,操作习惯有的喜欢双击鼠标重复提交,有的故意为之,在投票操作中这种比较常见。
Go语言中常见的两种方式,第一种是在表单添加一个带有唯一隐藏字段。在验证表单时,先检查带有唯一值的表单是否已经提交过了。如果已经提交过了,就拒绝再次提交;如果没有,则处理表单内容。第二种方式采用Ajax模式提交表单,当表单提交后,通过javascript来禁用表单的递交按钮。
例子4-Html代码:
<html>
<head>
<title>登陆<title>
</head>
<body>
<form action=”http://127.0.0.1:9090/login”method=”post”>
<inputtype=”radio” name=”gender” value=”1”> 男
<inputtype=”radio” name=”gender” value=”2”> 女
用户名:<input type=”text”name=”username”>
密码:<input type=”password” name=”password”>
<input type=”hidden” name=”token” value=”{{.}}”>
<input type=”submit” value=”登陆”>
</body>
</html>
例子4-服务器端代码:
fucn login(w http.ResponseWriter,r*http.Request){
fmt.Println(“method:”,r.Method)//获取请求的方法
if r.Method==”GET”{
crutime:=time.Now().Unix()
h:=md5.New()
io.WritheString(h,strconv.FormatInt(crutime,10))
token:=fmt.Sprintf(“%x”,h.Sum(nil))
t,_:=template.ParseFiles(“login.gtpl”)
t.Execute(w,token)
}else{
//请求的登陆数据,那么执行登陆的逻辑判断
r.ParseForm()
token:=r.Form.Get(“token”)
if token!=””{
//验证token的合法性
}else{
//不存在token报错
}
fmt.Println(“username length:”,len(r.Form[“username”][0]))
//输出到服务器端
fmt.Println(“username:”,template.HTMLEscapeString(r.Form.Get(“username”)))
fmt.Println(“password:”,template.HTMLEscapeString(r.Form.Get(“password”)))
}
}
在增加token之后客户端输出的源码,token字段的值:<input type=”hidden” name=”token” value=”eff540df8eacc98662563b95af608f5f”>利用隐藏字段token然后通过MD5来获取唯一值,保持表单唯一性。本节就到这,持续的学习与实践才是我们前进的路,加油吧!
请开始你的表演,践行,践行,再践行。未完待续。。。
网友评论