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如何替换某个文件中的字符串
Apr 25 Golang
goland 恢复已更改文件的操作
Apr 28 Golang
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
May 05 Golang
解决Goland 同一个package中函数互相调用的问题
May 06 Golang
Golang二维数组的使用方式
May 28 Golang
go语言中http超时引发的事故解决
Jun 02 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
golang操作redis的客户端包有多个比如redigo、go-redis
Apr 14 Golang
Golang 入门 之url 包
May 04 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+javascript模拟Matrix画面
2006/10/09 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
PHP中ini_set和ini_get函数的用法小结
2014/02/18 PHP
PHP如何通过AJAX方式实现登录功能
2015/11/23 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
ThinkPHP3.2框架操作Redis的方法分析
2019/05/05 PHP
用Jquery实现可编辑表格并用AJAX提交到服务器修改数据
2009/12/27 Javascript
JavaScript和ActionScript的交互实现代码
2010/08/01 Javascript
基于OO的动画附加插件,可以实现弹跳、渐隐等动画效果 分享
2013/06/24 Javascript
js字符串截取函数substr substring slice使用对比
2013/11/27 Javascript
解析页面加载与js函数的执行 onload or ready
2013/12/12 Javascript
后台获取ZTREE选中节点的方法
2015/02/12 Javascript
浅谈JavaScript中的string拥有方法的原因
2015/08/28 Javascript
详解webpack-dev-server使用http-proxy解决跨域问题
2018/01/13 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
2018/10/08 Javascript
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
原生JavaScript实现滑动拖动验证的示例代码
2019/12/06 Javascript
Python装饰器的函数式编程详解
2015/02/27 Python
使用Python神器对付12306变态验证码
2016/01/05 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
Python爬虫PyQuery库基本用法入门教程
2018/08/04 Python
python使用requests.session模拟登录
2019/08/09 Python
Python结合Window计划任务监测邮件的示例代码
2020/08/05 Python
HTML5到底会有什么发展?HTML5的前景展望
2015/07/07 HTML / CSS
AmazeUI 图标的示例代码
2020/08/13 HTML / CSS
日本无添加化妆品:HABA
2016/08/18 全球购物
秘书岗位职责
2013/11/18 职场文书
丧事主持词大全
2014/04/02 职场文书
司法局群众路线教育实践活动整改措施
2014/09/17 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
学校组织向国旗敬礼活动方案(中小学适用)
2014/09/27 职场文书
来探秘“德国中小企业”的成功之道
2019/07/26 职场文书
一文带你探究MySQL中的NULL
2021/11/11 MySQL
Python jiaba库的使用详解
2021/11/23 Python
Win11控制面板快捷键是什么?Win11打开控制面板的方法汇总
2022/07/07 数码科技