1.3 网络请求

1.3 网络请求

1.3.1【必须】资源请求过滤验证

  • 使用"net/http"下的方法http.Get(url)、http.Post(url, contentType, body)、http.Head(url )、http.PostForm(url, data)、http.Do(req)时,如变量值外部可控(指从参数中动态获取),应对请求目标进行严格的安全校验。

  • 如请求资源域名归属固定的范围,如只允许a.qq.com和b.qq.com,应做白名单限制。如不适用白名单,则推荐的校验逻辑步骤是:

    • 第 1 步、只允许HTTP或HTTPS协议

    • 第 2 步、解析目标URL,获取其HOST

    • 第 3 步、解析HOST,获取HOST指向的IP地址转换成Long型

    • 第 4 步、检查IP地址是否为内网IP,网段有:

// 以RFC定义的专有网络为例,如有自定义私有网段亦应加入禁止访问列表。
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
127.0.0.0/8
* 第 5 步、请求URL

* 第 6 步、如有跳转,跳转后执行1,否则绑定经校验的ip和域名,对URL发起请求
  • 官方库encoding/xml不支持外部实体引用,使用该库可避免xxe漏洞
  import (
      "encoding/xml"
      "fmt"
      "os"
  )

  func main() {
      type Person struct {
          XMLName   xml.Name `xml:"person"`
          Id        int      `xml:"id,attr"`
          UserName string   `xml:"name>first"`
          Comment string `xml:",comment"`
      }

      v := &Person{Id: 13, UserName: "John"}
      v.Comment = " Need more details. "

      enc := xml.NewEncoder(os.Stdout)
      enc.Indent("  ", "    ")
      if err := enc.Encode(v); err != nil {
          fmt.Printf("error: %v\n", err)
      }

  }