RAVEN(CI/CD 风险分析与漏洞枚举) 是一款强大的安全工具,专为大规模扫描 GitHub Actions CI 工作流并将发现的数据整合到 Neo4j 数据库中而设计。由 Cycode 研究团队开发和维护。
借助 Raven,我们能够识别并报告 GitHub 上一些最受欢迎的仓库中的安全漏洞,包括:
我们已将所有通过 Raven 发现的漏洞列在了工具的名人堂中。
该工具提供以下功能来扫描和分析潜在的 CI/CD 漏洞:
Raven 的可能用途:
该工具为 CI/CD 安全分析提供了可靠且可扩展的解决方案,使用户能够查询错误配置并获得关于其代码库安全状况的宝贵见解。
在过去的一年中,Cycode Labs 对 CI/CD 系统的基本安全问题进行了广泛研究。我们深入研究了多个系统、数千个项目以及多种配置。结论很明确——将安全责任委托给开发者的模式已经失败。这一点在我们之前的内容中多次得到证实:
上述每个漏洞都有其独特特征,使得开发者几乎不可能跟上最新的安全趋势。不幸的是,每个漏洞都有一个共同点——每次利用都可能影响数百万受害者。
正是出于这些原因,Raven 被创建为一个用于 CI/CD 安全工作流分析(首次用例是针对 GitHub Actions)的框架。在我们的关注点中,我们审查了复杂的场景,其中每个问题本身并不构成威胁,但组合起来却构成严重威胁。
要开始使用 Raven,请按照以下安装说明进行操作:
步骤 1:安装 Raven 包```bash pip3 install raven-cycode
**第二步**:搭建本地Redis服务器和Neo4j数据库```bash
docker run -d --name raven-neo4j -p7474:7474 -p7687:7687 --env NEO4J_AUTH=neo4j/123456789 --volume raven-neo4j:/data neo4j:5.12
docker run -d --name raven-redis -p6379:6379 --volume raven-redis:/data redis:7.2.1
另一种设置环境的方法是运行我们提供的docker compose文件:```bash git clone https://github.com/CycodeLabs/raven.git cd raven make setup
**步骤 3**: 运行 Raven Downloader
账户模式:```bash
raven download account --token $GITHUB_TOKEN --account-name RavenDemo
爬取模式:```bash raven download crawl --token $GITHUB_TOKEN --min-stars 1000
**步骤4**:运行 Raven Indexer```bash
raven index
步骤 5:通过报告器检查结果```bash raven report --format raw
此时,可以通过连接 http://localhost:7474/browser/ 来查看 Neo4j 数据库中的数据。
### 前提条件
- Python 3.9+
- Docker Compose v2.1.0+
- Docker Engine v1.13.0+
## 基础设施
Raven 使用两个主要的 Docker 容器:Redis 和 Neo4j。
`make setup` 将运行 `docker compose` 命令来准备该环境。

## 使用
该工具包含三个主要功能:`download`、`index` 和 `report`。
### 下载
#### 下载账户仓库```bash
usage: raven download account [-h] --token TOKEN [--debug] [--redis-host REDIS_HOST] [--redis-port REDIS_PORT] [--clean-redis] (--account-name ACCOUNT_NAME | --personal)
options:
-h, --help show this help message and exit
--token TOKEN GITHUB_TOKEN to download data from Github API (Needed for effective rate-limiting)
--debug Whether to print debug statements, default: False
--redis-host REDIS_HOST
Redis host, default: localhost
--redis-port REDIS_PORT
Redis port, default: 6379
--clean-redis, -cr Whether to clean cache in the redis, default: False
--account-name ACCOUNT_NAME
Account name for downloading the workflows, can be used multiple times
--personal Download repositories owned by the authenticated user
usage: raven download crawl [-h] --token TOKEN [--debug] [--redis-host REDIS_HOST] [--redis-port REDIS_PORT] [--clean-redis] [--max-stars MAX_STARS] [--min-stars MIN_STARS]
options: -h, --help show this help message and exit --token TOKEN GITHUB_TOKEN to download data from Github API (Needed for effective rate-limiting) --debug Whether to print debug statements, default: False --redis-host REDIS_HOST Redis host, default: localhost --redis-port REDIS_PORT Redis port, default: 6379 --clean-redis, -cr Whether to clean cache in the redis, default: False --max-stars MAX_STARS Maximum number of stars for a repository --min-stars MIN_STARS Minimum number of stars for a repository, default: 1000
### 目录```bash
usage: raven index [-h] [--redis-host REDIS_HOST] [--redis-port REDIS_PORT] [--clean-redis] [--neo4j-uri NEO4J_URI] [--neo4j-user NEO4J_USER] [--neo4j-pass NEO4J_PASS]
[--clean-neo4j] [--debug]
options:
-h, --help show this help message and exit
--redis-host REDIS_HOST
Redis host, default: localhost
--redis-port REDIS_PORT
Redis port, default: 6379
--clean-redis, -cr Whether to clean cache in the redis, default: False
--neo4j-uri NEO4J_URI
Neo4j URI endpoint, default: neo4j://localhost:7687
--neo4j-user NEO4J_USER
Neo4j username, default: neo4j
--neo4j-pass NEO4J_PASS
Neo4j password, default: 123456789
--clean-neo4j, -cn Whether to clean cache, and index from scratch, default: False
--debug Whether to print debug statements, default: False
usage: raven report [-h] [--redis-host REDIS_HOST] [--redis-port REDIS_PORT] [--clean-redis] [--neo4j-uri NEO4J_URI] [--neo4j-user NEO4J_USER] [--neo4j-pass NEO4J_PASS] [--clean-neo4j] [--tag {injection,unauthenticated,fixed,priv-esc,supply-chain,best-practice,endoflife,reconnaissance}] [--severity {info,low,medium,high,critical}] [--query_ids RQ-1,..,RQ-16] [--queries-path QUERIES_PATH] [--format {raw,json}] {slack} ...
positional arguments: {slack} slack Send report to slack channel
options: -h, --help show this help message and exit --redis-host REDIS_HOST Redis host, default: localhost --redis-port REDIS_PORT Redis port, default: 6379 --clean-redis, -cr Whether to clean cache in the redis, default: False --neo4j-uri NEO4J_URI Neo4j URI endpoint, default: neo4j://localhost:7687 --neo4j-user NEO4J_USER Neo4j username, default: neo4j --neo4j-pass NEO4J_PASS Neo4j password, default: 123456789 --clean-neo4j, -cn Whether to clean cache, and index from scratch, default: False --tag {injection,unauthenticated,fixed,priv-esc,supply-chain,best-practice,endoflife,reconnaissance}, -t {injection,unauthenticated,fixed,priv-esc,supply-chain,best-practice,endoflife,reconnaissance} Filter queries with specific tag --severity {info,low,medium,high,critical}, -s {info,low,medium,high,critical} Filter queries by severity level (default: info) --query_ids RQ-1,..,RQ-16, -id RQ-1,..,RQ-16 Filter queries by query ids (example: RQ-2,RQ-8) --queries-path QUERIES_PATH, -dp QUERIES_PATH Queries folder (default: library) --format {raw,json}, -f {raw,json} Report format (default: raw)
## Examples
检索与任何账户(用户/组织)关联的所有工作流和操作。```bash
raven download account --token $GITHUB_TOKEN --account-name microsoft --account-name google --debug
抓取所有可公开访问的GitHub仓库。```bash raven download crawl --token $GITHUB_TOKEN --min-stars 100 --max-stars 1000 --debug
在完成下载过程或被Ctrl+C中断后,继续将所有工作流和操作索引到Neo4j数据库中。```bash
raven index --debug
现在,我们可以使用我们的查询库生成报告。```bash raven report --severity high --tag injection --tag unauthenticated
## 速率限制
为了实现有效的速率限制,您应提供一个 Github 令牌。
对于经过身份验证的用户,适用以下速率限制:
- 代码搜索 - 每分钟 30 次查询
- 任何其他 API - 每小时 5000 次
## 研究知识库
- [问题注入](https://github.com/CycodeLabs/raven/blob/main/docs/Issue%20Injections/README.md)
- [拉取请求注入](https://github.com/CycodeLabs/raven/blob/main/docs/Pull%20Request%20Injections/README.md)
- [工作流运行注入](https://github.com/CycodeLabs/raven/blob/main/docs/Multi%20Prerequisite%20Exploits/README.md)
- [CodeSee 注入](https://github.com/CycodeLabs/raven/blob/main/docs/Codesee%20Injections/README.md)
## 当前限制
- 可以通过引用包含 `Dockerfile`(不含 `action.yml`)的文件夹来运行外部操作。目前尚不支持此行为。
- 可以通过 `docker://...` URL 引用 Docker 容器来运行外部操作。目前尚不支持此行为。
- 可以通过本地引用来运行操作。这会带来复杂行为,因为它可能来自之前已签出的不同仓库。当前行为是尝试在现有仓库中查找该操作。
- 我们并未对整个工作流结构进行建模。如果需要更多字段,请按照[贡献](https://github.com/CycodeLabs/raven/blob/main/CONTRIBUTING.md)指南提交拉取请求。
## 未来研究工作
- 实现污点分析。用例示例——用户可以将拉取请求标题(可控参数)传递给名为 `data` 的操作参数。该操作参数可能在运行命令中使用:`- run: echo ${{ inputs.data }}`,这为代码执行创造了路径。
- 扩展对 `GITHUB_ENV` 有害滥用的研究。这也可能利用之前的污点分析。
- 研究 `actions/github-script` 是否具有有趣的威胁态势。如果是,可以在图中进行建模。
## 许可证
[Apache 许可证 2.0](https://github.com/CycodeLabs/raven/blob/main/LICENSE.md)
## 名人堂——使用 Raven 发现并披露的漏洞
| 名称 | 星标 | 修复 | 其他来源 |
| ------ | -------- | ---- | -------------------- |
| [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) |  | CodeSee 包更新,[0871341](https://github.com/freeCodeCamp/freeCodeCamp/commit/0871341c9cbf96ab455bc3e0bce636e2ef2a2be2) | [博客](https://cycode.com/blog/cycode-secures-thousands-of-open-source-projects/) |
| [Significant-Gravitas/AutoGPT](https://github.com/Significant-Gravitas/AutoGPT) |  | [cdae7f8](https://github.com/Significant-Gravitas/AutoGPT/pull/6313/commits/cdae7f84ce0b2879fdcc1fa04956cdaa42a07bfb) | | [storybookjs/storybook](https://github.com/storybookjs/storybook) |  | [ffb8558](https://github.com/storybookjs/storybook/commit/ffb8558b7e5df4644299e5ec7009ade6ca1a721c) | [博客](https://cycode.com/ci-story-how-we-found-critical-vulnerabilities-in-storybook-project/) |
| [tiangolo/fastapi](https://github.com/tiangolo/fastapi) |  | [9efab1b](https://github.com/tiangolo/fastapi/commit/9efab1bd96ef061edf1753626573a0a2be1eef09) | [LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7011753940283203584/) |
| [withastro/astro](https://github.com/withastro/astro) |  | [650fb1a](https://github.com/withastro/astro/commit/650fb1aa51a1c843c10bc89a11732b45a6345b00) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [statelyai/xstate](https://github.com/statelyai/xstate) |  | CodeSee 包更新 | [博客](https://cycode.com/blog/cycode-secures-thousands-of-open-source-projects/) |
| [bazelbuild/bazel](https://github.com/bazelbuild/bazel) |  | [3561f07](https://github.com/bazelbuild/continuous-integration/commit/3561f079e0414d31ebba923815695e1e714937cb) | [博客](https://cycode.com/blog/cycode-discovers-a-supply-chain-vulnerability-in-bazel/) |
| [docker-slim/docker-slim](https://github.com/docker-slim/docker-slim) |  | CodeSee 包更新 | [博客](https://cycode.com/blog/cycode-secures-thousands-of-open-source-projects/) |
| [microsoft/fluentui](https://github.com/microsoft/fluentui) |  | [2ea6195](https://github.com/microsoft/fluentui/commit/2ea6195152131766641311ee5604e746b578d8e7) | [博客](https://cycode.com/blog/analyzing-the-vulnerability-that-could-have-compromised-microsoft-365-users/) |
| [tiangolo/sqlmodel](https://github.com/tiangolo/sqlmodel) |  | [cf36b2d](https://github.com/tiangolo/sqlmodel/commit/cf36b2d9baccf527bc61071850f102e2cd8bf6bf) | [LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7011753940283203584/) |
| [tiangolo/typer](https://github.com/tiangolo/typer) |  | [0c106a1](https://github.com/tiangolo/typer/commit/0c106a169e5e3c7df6f98e32a6d8405c985b695a) | [LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7011753940283203584/) |
| [juspay/hyperswitch](https://github.com/juspay/hyperswitch) |  | [a052f9a](https://github.com/juspay/hyperswitch/pull/2797/commits/a052f9a9c921ec0ff8c526097841be5777faf835) | |
| [autogluon/autogluon](https://github.com/autogluon/autogluon) |  | [ca18fa9](https://github.com/autogluon/autogluon/commit/ca18fa9fa2071f670125fd19700cf3570a6b5119) | |
| [apache/camel](https://github.com/apache/camel) |  | [02e512a](https://github.com/apache/camel/pull/11879/commits/02e512ae1ab0a471e80d86096ea79b45789aa105) | | [liquibase/liquibase](https://github.com/liquibase/liquibase) |  | [3278525](https://github.com/liquibase/liquibase/commit/3278525eaf974daea20808926f9a6816aecd01a7) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [ossf/scorecard](https://github.com/ossf/scorecard) |  | [c9f582b](https://github.com/ossf/scorecard/commit/c9f582b620a57a1a476f4e3add505ff50c51a774) | |
| [Ombi-app/Ombi](https://github.com/Ombi-app/Ombi) |  | [5cc0d77](https://github.com/Ombi-app/Ombi/commit/5cc0d7727d72fe1fee8a3f6c3874d44a5b785de4) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [wireapp/wire-ios](https://github.com/wireapp/wire-ios) |  | [9d39d6c](https://github.com/wireapp/wire-ios/commit/9d39d6c93b5a58a0bc8c1aba10e0d67756359630) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [cloudscape-design/components](https://github.com/cloudscape-design/components) |  | [2921d2d](https://github.com/cloudscape-design/.github/commit/2921d2d1420fef5b849d5aecbcfb9138ac6b9dcc) | |
| [DynamoDS/Dynamo](https://github.com/DynamoDS/Dynamo) |  | 已禁用工作流 | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [fauna/faunadb-js](https://github.com/fauna/faunadb-js) |  | [ee6f53f](https://github.com/fauna/faunadb-js/commit/ee6f53f9c985bde41976743530e3846dee058587) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
| [apache/incubator-kie-kogito-runtimes](https://github.com/apache/incubator-kie-kogito-runtimes) |  | [53c18e5](https://github.com/apache/incubator-kie-kogito-runtimes/commit/53c18e5372e5306e0aa580f201f820b80359ad11) | [博客](https://cycode.com/github-actions-vulnerabilities/) |
## 想要更多关于 CI/CD 安全、应用安全以及 ASPM 的内容?欢迎了解 Cycode
如果您喜欢 Raven,您可能也会喜欢我们的 [Cycode](https://cycode.com/?utm_source=github_website&utm_medium=referral&utm_campaign=raven_page) 平台,它提供了更强大的功能,用于在软件交付过程中实现漏洞的可视性、优先级排序和修复。
如果您对稳健的、以研究为驱动的流水线安全、应用安全或 ASPM 解决方案感兴趣,请随时联系我们,或通过以下链接申请演示:[https://cycode.com/book-a-demo/](https://cycode.com/book-a-demo/?utm_source=github_website&utm_medium=referral&utm_campaign=raven_page)。