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/scorecard#public-data )中。

Scorecard API 发布

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

地址:https://api.securityscorecards.dev

为什么 Scorecard API 如此有意义?

由于软件供应链对于整个项目的安全来说极其重要,因此最好能有一个明确的安全策略。在理想状况下,机器检查/强制执行可以确保新的依赖项的高质量标准,减缓不必要的依赖项增加,并解决结构性问题(如项目中所包含重复的依赖项、已知有问题的依赖项)。

我们的策略可以解决如下问题:

随着时间的推移,依赖项是如何变化的?

  • 那些依赖项做了什么?

  • 它们如何影响项目安全?

  • 它们如何更新?

  • 你如何限制你的暴露?

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

  • 依赖项相对于其上游的陈旧程度

  • 是否有适用于项目依赖项的任何已知的常见漏洞和暴露(CVE)

  • 外部依赖项在多大程度上遵循最佳实践,例如,代码审查、更新依赖项、双因子认证(2FA)、漏洞披露过程、定期发布实践等

以下例子可以说明Envoy如何使用明确的外部依赖性策略:

https://github.com/envoyproxy/envoy/blob/main/DEPENDENCY_POLICY.md

使用 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/naveensrinivasan/scorecard-api-demo

Scorecard 项目可以让用户更容易测量依赖项的健康程度,并根据其创建策略。而Scorecard API 让依赖项策略的自动化和执行都更轻松了。在未来的版本中,Seal 软件供应链防火墙计划集成 Scorecard API ,更好地保障用户依赖项安全。

依赖项安全检测新利器:Scorecard API的更多相关文章

  1. 从ASP.Net Core Web Api模板中移除MVC Razor依赖项

    前言 :本篇文章,我将会介绍如何在不包括MVC / Razor功能和包的情况下,添加最少的依赖项到ASP.NET Core Web API项目中. 一.MVC   VS WebApi (1)在ASP. ...

  2. C#中缓存的简单方法及使用Sql设置缓存依赖项

    概述 使用Cache高速缓存可以提高数据的读取速度,减少服务器与客户端之间的数据交互.因为Cache一经创建就会占用服务器上的资源,所以Cache并不是越多越好,一般用于数据较固定,使用较频繁的地方. ...

  3. 第 6 章 —— 依赖项注入(DI)容器 —— Ninject

    有些读者只想理解 MVC 框架所提供的特性,而不想介入开发理念与开发方法学.笔者不打算让你改变 —— 这属于个人取向,而且你知道交付优质项目需要的是什么. 建议你至少粗略第看一看本章的内容,以明白哪些 ...

  4. ArcGIS API For Javascript :如何解决跨网不能正常获取依赖项的问题?

    一.前言 政企项目通常会在自组网以及保密网运行,有些单位甚至会有两个物理隔绝的网络存在.通常情况下我们会在两个网络中部署相同的地图服务和依赖项.但是也有其中一个网络密级很高没有服务器资源,不能单独部署 ...

  5. SparkR:数据科学家的新利器

    摘要:R是数据科学家中最流行的编程语言和环境之一,在Spark中加入对R的支持是社区中较受关注的话题.作为增强Spark对数据科学家群体吸引力的最新举措,最近发布的Spark 1.4版本在现有的Sca ...

  6. (30)导入时如何定制spring-boot依赖项的版本【转载】【从零开始学Spring Boot】

    此文章转载地址:http://www.tuicool.com/articles/RJJvMj3 请注重作者的版权. spring-boot通过maven的依赖管理为我们写好了很多依赖项及其版本,我们可 ...

  7. ASP.NET Core 1.0 中的依赖项管理

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  8. 目标平台、活动平台 配置,出现未能加载文件或程序集“xxx”或它的某一个依赖项报错

    今天在做动态加载程序集的时候,发现明明程序集存在的情况下,还是依然报“未能加载文件或程序集“xxx”或它的某一个依赖项报错”的错误,排除了程序和配置的错误后,怀疑是否是环境的问题,于是百度加msdn后 ...

  9. (转)这个API很“迷人”——新的Fetch API

    原文:https://hacks.mozilla.org/2015/03/this-api-is-so-fetching 原标题是This API is So Fetching,Fetching也可以 ...

随机推荐

  1. 017(Power Strings二刷)(KMP)

    题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1466 题目思路:不知道大家在KMP算法里有没有看见这么个句子 while(j<len) 这 ...

  2. IO流原理及流的分类

    IO原理 I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于 处理设备之间的数据传输.如读/写文件,网络通讯等. Java程序中,对于数据的输入/输出操作以"流(st ...

  3. 【cartographer_ros】四: 发布和订阅里程计odom信息

    上一节介绍了激光雷达Scan传感数据的订阅和发布. 本节会介绍里程计Odom数据的发布和订阅.里程计在cartographer中主要用于前端位置预估和后端优化. 官方文档: http://wiki.r ...

  4. SpringCloud Gateway微服务网关实战与源码分析-上

    概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...

  5. MySQL语句与正则表达式

    正则表达式的作用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较.MySQL用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,过滤SELECT检索出的数据. 1.元字符说明 ...

  6. APISpace 让你快速获取安徒生童话故事

    <安徒生童话>是丹麦作家安徒生创作的童话集,共由166篇故事组成.该作爱憎分明,热情歌颂劳动人民.赞美他们的善良和纯洁的优秀品德:无情地揭露和批判王公贵族们的愚蠢.无能.贪婪和残暴. 接口 ...

  7. Web || Html_Css_JS

    第三阶段课程介绍: web前端 l 数据库 l SpringBoot Web前端-HTML l HTML作用: 负责搭建页面结构和内容 (盖房子) l 学习HTML主要学习的就是有哪些标签 文本相关标 ...

  8. Command 'ifconfig' not found, but can be installed with: sudo apt install net-tools解决方法

    VMware下安装的Ubuntu 当使用ifconfig命令查看网卡配置信息的时候出错 尝试了很多方法都解决不了,直到输入了下面的内容: 然后自己就更新了很多东西 之后重新输入ifconfig命令就能 ...

  9. php和js的不定参

    function my_func() { $args = func_get_args(); print_r($args); } my_func('php','java','node.js'); jav ...

  10. Docker-Compose和Docker Network的应用

    1 # Docker-Compose分为两部分 2 # 一.Docker-Compose.yml 3 # 二.Docker-Compose 命令 4 5 # 桌面板的Docker(Win.Mac)会默 ...