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 相关文章推荐
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
使用golang编写一个并发工作队列
May 08 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
golang内置函数len的小技巧
Jul 25 Golang
Go语言并发编程 sync.Once
Oct 16 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
golang为什么要统一错误处理
Apr 03 Golang
Golang bufio详细讲解
Apr 21 Golang
Golang 结构体数据集合
Apr 22 Golang
Golang并发工具Singleflight
May 06 Golang
Go 内联优化让程序员爱不释手
Jun 21 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的call_user_func传reference引发的思考
2010/07/23 PHP
PHP文件生成的图片无法使用CDN缓存的解决方法
2015/06/20 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
Laravel5.7 数据库操作迁移的实现方法
2019/04/12 PHP
浅谈Laravel POST,PUT,PATCH 路由的区别
2019/10/15 PHP
document.all的一个比较完整的总结及案例
2013/01/31 Javascript
使用jquery.validate自定义方法实现&quot;手机号码或者固话至少填写一个&quot;的逻辑验证
2014/09/01 Javascript
Node.js开发之访问Redis数据库教程
2015/01/14 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
原生javascript实现addClass,removeClass,hasClass函数
2016/02/25 Javascript
基于jQuery和hwSlider实现内容左右滑动切换效果附源码下载(一)
2016/06/22 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
关于Bootstrap按钮组件消除黄框的方法
2017/05/19 Javascript
分享ES6的7个实用技巧
2018/01/18 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
2018/08/23 jQuery
Node.js JSON模块用法实例分析
2019/01/04 Javascript
vscode vue 文件模板的配置方法
2019/07/23 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
2020/06/03 Javascript
基于python中pygame模块的Linux下安装过程(详解)
2017/11/09 Python
从DataFrame中提取出Series或DataFrame对象的方法
2018/11/10 Python
关于PyTorch 自动求导机制详解
2019/08/18 Python
python日志模块logbook使用方法
2019/09/19 Python
Python Celery多队列配置代码实例
2019/11/22 Python
python实现二分类的卡方分箱示例
2019/11/22 Python
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
ORACLE第二个十问
2013/12/14 面试题
创伤外科专业推荐信范文
2013/11/19 职场文书
网络专业学生个人的自我评价
2013/12/16 职场文书
八年级历史教学反思
2014/01/10 职场文书
计算机专业优秀大学生自我总结
2014/01/21 职场文书
数学系个人求职信范文
2014/01/30 职场文书
化工操作工岗位职责
2014/04/29 职场文书
党课培训心得体会
2014/09/02 职场文书
电影雷锋观后感
2015/06/10 职场文书