不要相信用户输入, 自己的也不行

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2024/01/22/do-not-trust-user-input/

这片文章记录了自己的一个 低级错误。 浪费了我接近一个小时的时间。

1. 背景介绍

大概背景是公司换了新的 API 网关, 所有项目都要重新介入。

研发团队接入之后, 需要帮他们验证测试, 于是用 go 写了一个简单的工具。

但是实际运行结果

time=2024-01-20 level=ERROR msg="Failed: StatusCode = 400" env=dev region=us target=https://example.com/app/status caller=verifier.go:47#Scan

无论怎调整 API 和参数 都是 400错误(Bad Request), 哪怕是最简单的 健康检查接口 也是如此。

2. 原因

检查完代码之后, 确实找不到什么问题。 没办法,只能从配置开始慢慢检查。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# app:
name: appname
envs: dev,qas,prd
regions: r1,r2
uris:
  - method: get
    path: /appname/status
  - method: post
    path: /appname/v1/others
    type: application/json
    data:
      name: zhangsan
      age: 18

经过一番对比检查, 最后发现了是 method 值的问题。

细心你的你可能已经发现, 这里 method 值是小写。 而 http 请求中 method 值是大写的。

解决方法就很简单了, 在请求之前 强制转换成大写即可 。 截取代码如下。

1
2
3
4
5
6
httpMethod := uri.Method // get, Get

// 转换大写
httpMethod = strings.ToUpper(uri.Method) // GET

req := protocol.NewRequest(httpMethod, target, nil)

3. 总结

排查经过和反思

3.1. 排查经过

  1. 查看代码: 这部分确实浪费了一些时间。

    1. 觉得代码没问题, 检查 API, 使用 Postman 对比测试。
    2. API 没问题, 查看代码逻辑。 检查哪里缺少 header, 哪里 body 处理错误。
  2. 检查配置: 主要集中检查 结构体中的 字段 Tag 是否与 配置字段 否能对上。

    1. tag 名字是否有错误拼写。
    2. tag 名字是否被修改过。
  3. 检查字段值: 在之前没有 debug 的地方加入 log.Debug 查看是否符合预期。

3.2. 反思

为什么会出现这种问题呢?

  1. 平常用使用的都是类似 http.MethodGet 这样的变量, 虽然知道后面是大写, 但是没出过问题, 所以印象不够深刻。
  2. 还是太轻信自己了。