乐趣区

关于开源项目介绍:依赖项安全检测新利器Scorecard-API

Scorecard 是 OpenSSF 旗下的开源我的项目,用于评估开源软件危险,本文由该项目标次要贡献者 Naveen 撰写。

古代软件是建设在数百个甚至数千个第三方开源组件之上的,这些通常被称为依赖项。它们能够帮忙开发团队疾速迭代并放弃生产力。

因为生产力的晋升,大部分企业正在疾速采纳开源软件(OSS),导致承载要害工作的应用程序依赖于成千上万的间接和传递依赖项。随着开源软件包正在成为歹意用户的攻打指标,这些依赖项的健康状况曾经成为整个供应链平安至关重要的局部。

一个依赖项的衰弱水平牵涉到诸多影响因素:它是否被良好保护?它是否常常更新?该我的项目是否有多个维护者?或者当其中一个维护者来到之后,这个我的项目是否会进行运行?在代码中是否有重大的破绽?

无论何时,当你思考要引入一个新的依赖项时,如果能取得该我的项目衰弱和平安水平的评分将帮忙你评估该我的项目是否平安。那么 OpenSSF Scorecard 将是你的不二之选,在之前的文章中咱们也对 OpenSSF Scorecard 进行了拆解。目前,Seal 软件供应链防火墙曾经集成 Scorecard,对用户扫描进去的破绽进行评分,进而对其进行修复优先级的排序。

OpenSSF Scorecard 是一款自动化工具,用于评估与软件平安相干的几个重要启发式(heuristics)查看,并给每项查看从 0 -10 分打分。这些分数有助于理解须要改善的具体环节,以增强依赖项的平安。

其中一些查看是:

  • 决定我的项目在 PR 合并之前是否须要代码审查
  • 查看我的项目的默认分支和公布分支是否受到 GitHub 的分支爱护
  • 查看我的项目是否在源仓库生成可执行的二进制构件

诸如 envoy.proxytensorflowflutter 等出名我的项目都在应用 Scorecard,以彰显他们的安全意识。

以后,Scorecards 每周扫描超过 100 万个代码仓库,扫描后果会被贮存在 BigQuery(https://github.com/ossf/score…)中。

Scorecard API 公布

Scorecard API 已于本月初正式公布,它能够用于拜访可用的数据集,这让 Scorecard 的能力更上一层楼。

地址:https://api.securityscorecard…

为什么 Scorecard API 如此有意义?

因为软件供应链对于整个我的项目的平安来说极其重要,因而最好能有一个明确的安全策略。在现实情况下,机器查看 / 强制执行能够确保新的依赖项的高质量规范,减缓不必要的依赖项减少,并解决结构性问题(如我的项目中所蕴含反复的依赖项、已知有问题的依赖项)。

咱们的策略能够解决如下问题:

随着工夫的推移,依赖项是如何变动的?

  • 那些依赖项做了什么?
  • 它们如何影响我的项目平安?
  • 它们如何更新?
  • 你如何限度你的裸露?

依赖项数量的快速增长会带来一些问题,比方难以跟踪:

  • 依赖项绝对于其上游的古老水平
  • 是否有实用于我的项目依赖项的任何已知的常见破绽和裸露(CVE)
  • 内部依赖项在多大程度上遵循最佳实际,例如,代码审查、更新依赖项、双因子认证(2FA)、破绽披露过程、定期公布实际等

以下例子能够阐明 Envoy 如何应用明确的内部依赖性策略:

https://github.com/envoyproxy…

应用 API 查看依赖项健康状况

如“木桶效应”所论述的那样,一只水桶能装多少水取决于其最短的那块木板。软件供应链的强壮水平也取决于其最单薄的环节。然而,在继续的工夫范畴内确定最单薄的环节并非易事。接下来,咱们将演示如何应用 Scorecard API 来评估 Golang 我的项目中的一组依赖项是否在其我的项目外部应用含糊测试,这是验证我的项目中是否存在零日破绽的办法之一。

要解决这一问题会波及到以下步骤:

1、获取指定我的项目中的依赖项和传递依赖列表:


// FetchDependencies parses the dependencies in the go.mod using the `go list command`
// This functions expects the directory to contain the go.mod file.
func FetchDependencies(directory string) ([]string, error) {
  modquery := `
  go list -m -f '{{if not (or  .Main)}}{{.Path}}{{end}}' all \
  | grep "^github" \
  | sort -u \
  | cut -d/ -f1-3 \
  | awk '{print $1}' \
  | tr '\n' ',' 
  `
  // Runs the modquery to generate the dependencies
  c := exec.Command("bash", "-c", fmt.Sprintf("cd %s;", directory)+modquery)
  data, err := c.Output()
  if err != nil {return nil, fmt.Errorf("failed to run go list: %w %s", err, string(data))
  }
  m := make(map[string]bool)
  parameters := []string{}
  result := append(parameters, strings.Split(string(data), ",")...)
  //filter the result to remove empty strings and duplicates
  for _, dep := range result {
    if dep != "" {m[dep] = true
    }
  }
  result = []string{}
  for dep := range m {result = append(result, dep)
  }
  return result, nil
}

以上代码只是为演示筹备的,不能在生产环境中应用。最初会返回我的项目中所有传递依赖项。

2、接下来,该函数从 API 中获取 Scorecard 的后果,并查看某个我的项目是否通过含糊测试:

func fuzzed(repo string) (bool, int, error) {
  //repo = "github.com/sigstore/sigstore"
  req, err := http.NewRequest("GET", fmt.Sprintf("https://api.securityscorecards.dev/projects/%s", repo), nil)
  if err != nil {panic(err)
  }
  req.Header.Set("Accept", "application/json")

  resp, err := http.DefaultClient.Do(req)
  if err != nil {return false, 0, err}
  defer resp.Body.Close()
  result, err := ioutil.ReadAll(resp.Body)
  if err != nil {return false, 0, err}
  var scorecard Scorecard
  err = json.Unmarshal(result, &scorecard)
  if err != nil {return true, 0, err}
  for _, check := range scorecard.Checks {
    if check.Name == "Fuzzing" {
      if check.Score >= 7 || check.Score < 0 {return true, check.Score, nil}
      return false, 0, nil
    }
  }
  return false, 0, nil
}

3、最初一步是将这两个函数联合起来,取得最终后果:

func main() {repoLocation := os.Args[1]
  if repoLocation == "" {panic("repoLocation is empty")
  }
  dependencies, err := FetchDependencies(repoLocation)
  if err != nil {panic(err)
  }
  fmt.Println("Projects that are being fuzzed:")
  var ops uint64
  var wg sync.WaitGroup

  for _, dep := range dependencies {
    dependency := dep
    wg.Add(1)
    go func(dep string) {defer wg.Done()
      maintained, score, err := fuzzed(dependency)
      if err != nil {return}
      if maintained && score >= 7 {atomic.AddUint64(&ops, 1)
        fmt.Println(dependency, score)
      }
    }(dep)
  }
  wg.Wait()
  fmt.Println("-----------------")
  fmt.Println("Total number of dependencies :", len(dependencies))
  fmt.Println("The number of dependencies that are fuzzed :", ops)
}

拜访以下链接能够查看残缺的工作实例:

https://github.com/naveensrin…

Scorecard 我的项目能够让用户更容易测量依赖项的衰弱水平,并依据其创立策略。而 Scorecard API 让依赖项策略的自动化和执行都更轻松了。在将来的版本中,Seal 软件供应链防火墙打算集成 Scorecard API,更好地保障用户依赖项平安。

退出移动版