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
go语言中json数据的读取和写出操作
Apr 28 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 Golang
golang goroutine顺序输出方式
Apr 29 Golang
golang switch语句的灵活写法介绍
May 06 Golang
使用golang编写一个并发工作队列
May 08 Golang
go xorm框架的使用
May 22 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
入门学习Go的基本语法
Jul 07 Golang
golang生成vcf通讯录格式文件详情
Mar 25 Golang
Golang并发工具Singleflight
May 06 Golang
GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结
Jun 14 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中memcache的应用
2013/06/18 PHP
php绘制一条弧线的方法
2015/01/24 PHP
PHP用反撇号执行外部命令
2015/04/14 PHP
详解PHP中array_rand函数的使用方法
2016/09/11 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
2016/09/23 PHP
phpstudy2020搭建站点的实现示例
2020/10/30 PHP
js跟随滚动条滚动浮动代码
2009/12/31 Javascript
jquery实现带单选按钮的表格行选中时高亮显示
2013/08/01 Javascript
JavaScript对内存分配及管理机制详细解析
2013/11/11 Javascript
如何正确使用Nodejs 的 c++ module 链接到 OpenSSL
2014/08/03 NodeJs
jQuery随机密码生成的方法
2015/03/09 Javascript
简单模拟node.js中require的加载机制
2016/10/27 Javascript
ajax 提交数据到后台jsp页面及页面跳转问题
2017/01/19 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
如何通过shell脚本自动生成vue文件详解
2019/09/10 Javascript
JS检测浏览器开发者工具是否打开的方法详解
2020/10/02 Javascript
移动端JS实现拖拽两种方法解析
2020/10/12 Javascript
[01:19:23]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第二场
2018/04/06 DOTA
[36:33]完美世界DOTA2联赛循环赛 Matador vs Forest 第一场 11.06
2020/11/06 DOTA
Django1.3添加app提示模块不存在的解决方法
2014/08/26 Python
python之wxPython菜单使用详解
2014/09/28 Python
python用插值法绘制平滑曲线
2021/02/19 Python
元组列表字典(莫烦python基础)
2019/04/03 Python
HTML5实现QQ聊天气泡效果
2017/06/26 HTML / CSS
检测浏览器是否支持html5视频的代码
2013/03/28 HTML / CSS
DVF官方网站:美国时装界尊尚品牌
2017/08/29 全球购物
Currentbody美国/加拿大:美容仪专家
2020/03/09 全球购物
金融专业推荐信
2013/11/14 职场文书
酒店员工检讨书
2014/02/18 职场文书
幼儿生日活动方案
2014/08/27 职场文书
党员群众路线对照检查材料
2014/08/31 职场文书
对外汉语专业大学生职业生涯规划范文
2014/09/13 职场文书
元旦主持词开场白
2015/05/29 职场文书
pytorch通过训练结果的复现设置随机种子
2021/06/01 Python
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers
SpringBoot使用AOP实现统计全局接口访问次数详解
2022/06/16 Java/Android