后端参数检验

最近在工作中处理后端参数校验时,总结了一些工具和方法,整理以便以后使用。

普通参数校验

如何在 Gin 框架中添加请求参数检验,在工作开发中,了解到一个开源工具:gotagexpr

GitHub 链接:https://github.com/bytedance/go-tagexpr

Demo 链接:https://github.com/Eminem-x/Learning/tree/main/Go/gin-doc-cn/gin-tagexpr

Request 请求类型中增加 tag,通过正则表达式的方式,在绑定入参时,即可判断是否合法,

当然如果参数之间有限制关系的话,似乎仍需要 if-else 去解决,这里也只是推荐此工具。

更通用的是,可以对此抽取成通用方法,针对每个请求都无需关心如何处理,只需定义规则即可,

中间件抽取如下,只需要传入 request 的地址即可进行校验:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package middlewares

import (
"github.com/bytedance/go-tagexpr/v2/validator"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)

var tagexpr = validator.New("tagexpr")

func ValidateArgs(c *gin.Context, request interface{}) error {

// 绑定request model
err := c.ShouldBindBodyWith(request, binding.JSON)

if err != nil {
return err
}

if tagexpr.Validate(request) != nil {
return ErrInputInvalid // 此处为自定义 error
}

return nil
}

图片校验

实际业务场景中,用户上传图片后,前端传入 tos,而后将 CDN 地址传到后端,后端存入数据库,

因为未对 uri 校验,修改图片链接为任意,此时打开请求该图片的页面后,会发起请求,造成损失,

由于请求是本地浏览器发起的,也可以做到类似于肉鸡的行为,解决方法如下:

  1. 后端下载传入链接的图片,判断是否为合法图片,具体实现,参考 GitHub 链接

    但是该方法并不可取,因为如果去请求传入的链接,所带来的影响更是不可控的,但可以用来判断是否为合法图片

  2. 根据 CDNHost 特征,进行简易的匹配判断即可

但是最好的方式还是整个流程托付给后端去做处理,可以保证整个过程的原子性和一致性。

CSRF 校验

跨站点请求伪造攻击是指攻击者通过设置好的陷阱,属于被动攻击,

强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,

有可能造成以下影响:

  • 利用已通过认证的用户权限更新设定信息
  • 利用已通过认证的用户权限购买商品
  • 利用已通过认证的用户权限在留言板上发表评论

比如攻击者在留言板部下陷阱:<img src="http://example.com/msg?q=hello">,就可以影响其他用户。

在实际业务场景中,也需要防止其他站点对项目站点进行恶意请求,例如下面的 html 文件:

1
2
3
4
5
6
7
8
9
<html>
<!-- CSRF PoC -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://examplle.com/xxx">
<input type="submit" value="Submit request" />
</form>
</body>
</html>

只需要添加 Header 即可,具体的开源代码参考:https://github.com/utrack/gin-csrf