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判断key是否在map中的代码
Apr 24 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
Go语言 go程释放操作(退出/销毁)
Apr 30 Golang
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
May 05 Golang
浅谈golang package中init方法的多处定义及运行顺序问题
May 06 Golang
go xorm框架的使用
May 22 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
Go语言设计模式之结构型模式
Jun 22 Golang
Golang并发操作中常见的读写锁详析
Aug 30 Golang
Golang表示枚举类型的详细讲解
Sep 04 Golang
深入理解go slice结构
Sep 15 Golang
Go中使用gjson来操作JSON数据的实现
Aug 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面向对象全攻略 (十七) 自动加载类
2009/09/30 PHP
smarty内置函数capture用法分析
2015/01/22 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
laravel框架中视图的基本使用方法分析
2019/11/23 PHP
静态的动态续篇之来点XML
2006/12/23 Javascript
基于jQuery的图片大小自动适应实现代码
2010/11/17 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
获取表单控件原始(初始)值的方法
2013/08/21 Javascript
jQuery插件实现文字无缝向上滚动效果代码
2016/02/25 Javascript
jQuery实现图片加载完成后改变图片大小的方法
2016/03/29 Javascript
微信小程序  自定义创建详细介绍
2016/10/27 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
JavaScript设计模式之代理模式简单实例教程
2018/07/03 Javascript
原生js实现获取form表单数据代码实例
2019/03/27 Javascript
vue实现购物车选择功能
2020/01/10 Javascript
js实现选项卡效果
2020/03/07 Javascript
python利用dir函数查看类中所有成员函数示例代码
2017/09/08 Python
Python实现简单生成验证码功能【基于random模块】
2018/02/10 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
使用TensorFlow直接获取处理MNIST数据方式
2020/02/10 Python
python读写文件write和flush的实现方式
2020/02/21 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
python时间序列数据转为timestamp格式的方法
2020/08/03 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
个人找工作自荐信格式
2013/09/21 职场文书
会计电算化应届生自荐信
2014/02/25 职场文书
《花瓣飘香》教学反思
2014/04/15 职场文书
亮剑精神演讲稿
2014/05/23 职场文书
项目经理任命书内容
2014/06/06 职场文书
特此通知格式
2015/04/27 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL
opencv检测动态物体的实现
2021/07/21 Python
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL