GO web编程(九——安全与加密)

原文作者:Go 技术论坛文档:《Go Web 编程()》
转自链接:https://learnku.com/docs/build-web-application-with-golang/4-form/3173

预防CSRF攻击

  • CSRF

Cross-site request forgery,跨站请求伪造。盗用登录信息,以你的身份模拟发送各种请求。

1.登录受信任网站A,并在本地生成Cookie。2.在不退出A的情况下,访问危险网站B。

  • 预防CSRF

服务端:正确使用GET、POST和Cookit;在非GET请求在增加伪随机数;

1、限定修改只能使用POST,当GET方式请求时就拒绝响应。

2、在非GET方式的请求中增加随机数:

生成随机数token

h := md5.New()
io.WriteString(h, strconv.FormatInt(crutime, 10))
io.WriteString(h, "ganraomaxxxxxxxxx")
token := fmt.Sprintf("%x", h.Sum(nil))

t, _ := template.ParseFiles("login.gtpl")
t.Execute(w, token)

输出token

<input type="hidden" name="token" value="{{.}}">

验证token

r.ParseForm()
token := r.Form.Get("token")
if token != "" {
    // 验证 token 的合法性
} else {
    // 不存在 token 报错
}

确保输入过滤

1、识别数据,搞清楚需要过滤的数据来自于哪里

2、过滤数据,弄明白我们需要什么样的数据

3、区分已过滤及被污染数据,如果存在攻击数据那么保证过滤之后可以让我们使用更安全的数据

  • 识别数据

GO通过r.ParseForm之后,把POST和GET的数据全部放在了r.Form里面。

  • 过滤数据

strconv包下面的字符串转换相关函数:Atoi,ParseBool,ParseFloat,ParseInt,转化格式

string包:Trim,ToLower,ToTitle。

regexp包:正则。

  • 区分过滤数据

约定把所有经过过滤的数据放入一个叫全局的Map变量中。这时需要用两个重要的步骤来防止被污染数据的注入:

每个请求都要初始化CleanMap为一个空Map。

加入检测及阻止来不外部数据源的变量名为CleanMap。

<form action="/whoami" method="POST">
    我是谁:
    <select name="name">
        <option value="astaxie">astaxie</option>
        <option value="herry">herry</option>
        <option value="marry">marry</option>
    </select>
    <input type="submit" />
</form>

对上面的表单做白名单处理:

r.ParseForm()
name := r.Form.Get("name")
CleanMap := make(map[string]interface{}, 0)
if name == "astaxie" || name == "herry" || name == "marry" {
    CleanMap["name"] = name
}

这样就可以确保CleanMap中的["name"]数据是合法的。

避免XSS攻击

Cross Site Scripting:"跨站脚本攻击"。为了不与CSS缩写混淆,故写为XSS。

XSS的攻击目标是为了盗取存储在客户端的cookie或者其他网站用于识别客户端身份的敏感信息。

XSS通常分为两类:

一是存储类的XSS:恶意用户的HTML输入WEB程序->进入数据库->Web程序->用户浏览器。

二是反射型XSS,主要做法是将脚本代码加入URL地址的请求参数里,请求参数进入程序后在页面直接输出,用户点击类似的恶意链接就可能受到攻击。

  • 预防XSS

坚决不要相信用户的任何输入,并过滤掉输入中的所有特殊字符,这样就能消灭绝大部分的XSS攻击。

1、过滤特殊字符。2、使用HTTP头指定类型

避免SQL注入

SQL注入攻击。

造成 SQL 注入的原因是因为程序没有有效过滤用户的输入,使攻击者成功的向服务器提交恶意的 SQL 查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。

表单:

<form action="/login" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input type="submit" value="登陆" /></p>
</form>

处理的SQL:

username:=r.Form.Get("username")
password:=r.Form.Get("password")
sql:="SELECT * FROM user WHERE username='"+username+"' AND password='"+password+"'"

如果用户输入的用户名是:myuser' or 'foo' = 'foo' --

那么SQL就会变为:SELECT * FROM user WHERE username='myuser' or 'foo' = 'foo' --'' AND password='xxx'

--在SQL里面是注释标记,那么查询语句就会中断,这就让攻击者在不知道任何合法用户名和密码的情况下登陆成功了。

  • 预防SQL注入

1、严格限制Web应用的数据库的操作权限。

2、检查输入的数据是否具有所期望的数据格式,严格限制变量的类型。

3、对进入数据库的特殊字符进行转义处理。

4、所有的查询语句建议使用数据库提供的参数化查询接口。例如使用database/sql包里面的查询函数Prepare和Query。

5、在应用发布之前使用专业的SQL注入检测工具进行检测。

6、避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,避免把代码里的SQL语句暴露出来。

存储密码

  • 普通法案

单向哈希:将铭文密码做单向哈希后存储。常用算法:SHA-256,SHA-1,MD5等

实现:

// import "crypto/sha256"
h := sha256.New()
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))

// import "crypto/sha1"
h := sha1.New()
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))

// import "crypto/md5"
h := md5.New()
io.WriteString(h, "需要加密的密码")
fmt.Printf("%x", h.Sum(nil))
  • 进阶方案

自己设置一个哈希算法。列如:加盐。

  • 专家方案

故意增加密码计算所需耗费的资源和时间,使得任何人都不可获得足够的资源建立所需的 rainbow table。

加密和解密数据

  • base64加解密

encoding/base64

加密

func base64Encode(src []byte) []byte {
   return []byte(base64.StdEncoding.EncodeToString(src))
}  

hello := "你好,世界! hello world"
debyte := base64Encode([]byte(hello))
fmt.Println(debyte)

解密

func base64Decode(src []byte) ([]byte, error) {
   return base64.StdEncoding.DecodeString(string(src))
}

// decode
    enbyte, err := base64Decode(debyte)
    if err != nil {
        fmt.Println(err.Error())
    }
  • 高级加解密

Go语言的crypto支持对称

crypto/aes 包:AES (Advanced Encryption Standard),又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。
crypto/des 包:DES (Data Encryption Standard),是一种对称加密标准,是目前使用最广泛的密钥系统,特别是在保护金融数据的安全中。曾是美国联邦政府的加密标准,但现已被 AE S 所替代。

posted @ 2021-05-18 22:11  Gumi-21  阅读(201)  评论(0)    收藏  举报