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 相关文章推荐
golang在GRPC中设置client的超时时间
Apr 27 Golang
golang json数组拼接的实例
Apr 28 Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 Golang
go xorm框架的使用
May 22 Golang
Go语言基础知识点介绍
Jul 04 Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 Golang
go goroutine 怎样进行错误处理
Jul 16 Golang
golang操作redis的客户端包有多个比如redigo、go-redis
Apr 14 Golang
Golang MatrixOne使用介绍和汇编语法
Apr 19 Golang
Go语言入门exec的基本使用
May 20 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
Windows下PHP5和Apache的安装与配置
2006/09/05 PHP
php根据日期判断星座的函数分享
2014/02/13 PHP
PHP基于cookie实现统计在线人数功能示例
2019/01/16 PHP
常用js脚本
2006/12/03 Javascript
让mayfish支持mysqli数据库驱动的实现方法
2010/05/22 Javascript
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
2015/08/06 Javascript
在Node.js中使用Javascript Generators详解
2016/05/05 Javascript
简单实现jQuery级联菜单
2017/01/09 Javascript
Angular实现双向折叠列表组件的示例代码
2017/11/21 Javascript
JS实现数组删除指定元素功能示例
2019/06/05 Javascript
javascript使用链接跨域下载图片
2019/11/01 Javascript
解决ele ui 表格表头太长问题的实现
2019/11/13 Javascript
nestjs中异常过滤器Exceptionfilter的具体使用
2021/02/07 Javascript
[42:34]VP vs VG 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python爬虫包 BeautifulSoup  递归抓取实例详解
2017/01/28 Python
Python 模拟购物车的实例讲解
2017/09/11 Python
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
在Pycharm中使用GitHub的方法步骤
2019/06/13 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
2020/02/07 Python
python opencv 检测移动物体并截图保存实例
2020/03/10 Python
keras训练浅层卷积网络并保存和加载模型实例
2020/07/02 Python
Python3+Appium安装及Appium模拟微信登录方法详解
2021/02/16 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
业务代表的岗位职责
2013/11/16 职场文书
销售顾问工作计划书
2014/08/15 职场文书
纪检干部对照检查材料
2014/08/22 职场文书
小班下学期个人总结
2015/02/12 职场文书
毕业纪念册寄语大全
2015/02/26 职场文书
2015年物业管理工作总结
2015/04/23 职场文书
2015年迎新晚会策划书
2015/07/16 职场文书
军训结束新闻稿
2015/07/17 职场文书
小学英语新课改心得体会
2016/01/22 职场文书
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js
win10电脑老是死机怎么办?win10系统老是死机的解决方法
2022/08/05 数码科技