1.2 文件操作

1.2.1【必须】 路径穿越检查

  • 在进行文件操作时,如果对外部传入的文件名未做限制,可能导致任意文件读取或者任意文件写入,严重可能导致代码执行。
  1. // bad: 任意文件读取
  2. func handler(w http.ResponseWriter, r *http.Request) {
  3. path := r.URL.Query()["path"][0]
  4. // 未过滤文件路径,可能导致任意文件读取
  5. data, _ := ioutil.ReadFile(path)
  6. w.Write(data)
  7. // 对外部传入的文件名变量,还需要验证是否存在../等路径穿越的文件名
  8. data, _ = ioutil.ReadFile(filepath.Join("/home/user/", path))
  9. w.Write(data)
  10. }
  11. // bad: 任意文件写入
  12. func unzip(f string) {
  13. r, _ := zip.OpenReader(f)
  14. for _, f := range r.File {
  15. p, _ := filepath.Abs(f.Name)
  16. // 未验证压缩文件名,可能导致../等路径穿越,任意文件路径写入
  17. ioutil.WriteFile(p, []byte("present"), 0640)
  18. }
  19. }
  20. // good: 检查压缩的文件名是否包含..路径穿越特征字符,防止任意写入
  21. func unzipGood(f string) bool {
  22. r, err := zip.OpenReader(f)
  23. if err != nil {
  24. fmt.Println("read zip file fail")
  25. return false
  26. }
  27. for _, f := range r.File {
  28. p, _ := filepath.Abs(f.Name)
  29. if !strings.Contains(p, "..") {
  30. ioutil.WriteFile(p, []byte("present"), 0640)
  31. }
  32. }
  33. return true
  34. }

1.2.2【必须】 文件访问权限

  • 根据创建文件的敏感性设置不同级别的访问权限,以防止敏感数据被任意权限用户读取。例如,设置文件权限为:-rw-r-----
  1. ioutil.WriteFile(p, []byte("present"), 0640)