go web 预防跨站脚本的实现方式


Posted in Golang onJune 11, 2021

一 点睛

现在的网站包含大量的动态内容以提高用户体验,比过去要复杂得多。所谓动态内容,就是根据用户环境和需要,Web 应用程序能够输出相应的内容。动态站点会受到一种名为“跨站脚本攻击”(Cross Site Scripting, 安全专家们通常将其缩写成 XSS)的威胁,而静态站点则完全不受其影响。

攻击者通常会在有漏洞的程序中插入 JavaScript、VBScript、 ActiveX 或 Flash 以欺骗用户。一旦得手,他们可以盗取用户帐户信息,修改用户设置,盗取或污染 cookie 和植入恶意广告等。

对 XSS 最佳的防护应该结合以下两种方式。

1 验证所有输入数据,有效检测攻击。

2 对所有输出数据进行适当的处理,以防止任何已成功注入的脚本在浏览器端运行。

针对第2种方式,Go 是怎样预防的呢?Go 的 html/template 包中带有下面几个函数可以帮助转义。

func HTMLEscape(w io.Writer, b []byte) // 把 b 进行转义之后写到 w

func HTMLEscapeString(s string) string // 转义 s 之后返回结果字符串

func HTMLEscaper(args ...interface{}) string // 支持多个参数一起转义,返回结果字符串

二 先看一个转义的例子

 1 代码

package main
 
import (
   "fmt"
   "html/template"
   "log"
   "net/http"
)
 
// 登录逻辑
func login(w http.ResponseWriter, r *http.Request) {
   fmt.Println("method:", r.Method) // 获取请求的方法
   if r.Method == "GET" {
      t, _ := template.ParseFiles("src\\goweb\\demo3\\login.html") // 解析模板
      t.Execute(w, nil)                                            // 渲染模板,并发送给前端
   } else {
      // 请求的是登陆数据,那么执行登陆的逻辑判断
      // 解析表单
      r.ParseForm()
      fmt.Println("username:", r.Form["username"])
      fmt.Println("password:", r.Form["password"])
      template.HTMLEscape(w, []byte(r.Form.Get("username"))) //输出到客户端
   }
}
 
func main() {
   http.HandleFunc("/login", login)         // 设置访问的路由
   err := http.ListenAndServe(":9090", nil) // 设置监听的端口
   if err != nil {
      log.Fatal("ListenAndServe: ", err)
   }
}

2 测试

如果在浏览器输入的 username 是 <script>alert()</script>,在浏览器上将看到下面内容。

go web 预防跨站脚本的实现方式

3 说明

Go 的 html/template 包默认帮忙过滤了 html 标签,将其进行了转义。

4 问题引出

如果要正常输出<script>alert()</script>,怎样处理呢?text/template 可以帮忙进行处理。

三 使用 text/template 进行处理

1 代码

package main
 
import (
   "log"
   "net/http"
   "text/template"
)
 
// 转义测试
func escape(w http.ResponseWriter, r *http.Request) {
   // 正常显示
   t, _ := template.New("foo").Parse(`{{define "T"}}Hello1, {{.}}!{{end}}`)
   t.ExecuteTemplate(w, "T", "<script>alert('you have been pwned')</script>")
}
 
func main() {
   http.HandleFunc("/escape", escape)       // 设置转义
   err := http.ListenAndServe(":9090", nil) // 设置监听的端口
   if err != nil {
      log.Fatal("ListenAndServe: ", err)
   }
}

2 测试

go web 预防跨站脚本的实现方式

3 说明

当使用 text/template 这个包时,可以正常显示。

四 使用 html/template 进行处理

1 代码

package main
 
import (
   "html/template"
   "log"
   "net/http"
)
 
// 转义测试
func escape(w http.ResponseWriter, r *http.Request) {
   // 转义显示
   t, _ := template.New("foo").Parse(`{{define "T"}}Hello1, {{.}}!{{end}}`)
   t.ExecuteTemplate(w, "T", "<script>alert('you have been pwned')</script>")
    // 正常显示
   t, _ = template.New("foo").Parse(`{{define "T"}}Hello2, {{.}}!{{end}}`)
   t.ExecuteTemplate(w, "T", template.HTML("<script>alert('you have been pwned')</script>"))
}
 
func main() {
   http.HandleFunc("/escape", escape)       // 设置转义
   err := http.ListenAndServe(":9090", nil) // 设置监听的端口
   if err != nil {
      log.Fatal("ListenAndServe: ", err)
   }
}

2 测试结果

go web 预防跨站脚本的实现方式

3 说明

当使用 html/template 这个包时,如果使用 template.HTML 函数,也可以正常显示,不使用 template.HTML 函数,转义显示。

以上就是go web 预防跨站脚本的详细内容,更多关于go web 预防跨站的资料请关注三水点靠木其它相关文章!

Golang 相关文章推荐
一文读懂go中semaphore(信号量)源码
Apr 03 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
May 05 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
Golang的继承模拟实例
Jun 30 Golang
go goroutine 怎样进行错误处理
Jul 16 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Go语言编译原理之变量捕获
Aug 05 Golang
Golang生成Excel文档的方法步骤
Go timer如何调度
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 #Golang
Golang中异常处理机制详解
Go语言实现Snowflake雪花算法
Jun 08 #Golang
go语言中http超时引发的事故解决
Jun 02 #Golang
Golang二维数组的使用方式
May 28 #Golang
You might like
浅谈php扩展imagick
2014/06/02 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP实现 APP端微信支付功能
2018/06/22 PHP
jQuery与其它库冲突的解决方法
2010/06/25 Javascript
Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
2011/10/12 Javascript
JQuery AJAX 中文乱码问题解决
2013/06/05 Javascript
window.location.href IE下跳转失效的解决方法
2014/03/27 Javascript
js设置document.domain实现跨域的注意点分析
2015/05/21 Javascript
AngularJS基础 ng-mouseover 指令简单示例
2016/08/02 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
javascript实现复选框全选或反选
2017/02/04 Javascript
nodejs个人博客开发第六步 数据分页
2017/04/12 NodeJs
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
2018/09/30 Javascript
基于Proxy的小程序状态管理实现
2019/06/14 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
vue语法自动转typescript(解放双手)
2019/09/18 Javascript
解决Vue 刷新页面导航显示高亮位置不对问题
2019/12/25 Javascript
Python中optparse模块使用浅析
2015/01/01 Python
python中引用与复制用法实例分析
2015/06/04 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
python实现五子棋小游戏
2020/03/25 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
Python读取JSON数据操作实例解析
2020/05/18 Python
如何在python中判断变量的类型
2020/07/29 Python
极度干燥澳大利亚官方网站:Superdry澳大利亚
2019/03/28 全球购物
四种会话跟踪技术
2015/05/20 面试题
大学生自荐信
2013/12/11 职场文书
办公室主任先进事迹
2014/01/18 职场文书
家长给学校的建议书
2014/05/15 职场文书
关于爱国的标语
2014/06/24 职场文书
改作风抓落实促发展心得体会
2014/09/10 职场文书
Nginx 配置 HTTPS的详细过程
2022/05/30 Servers