
GitHub Actions CI/CD 워크플로우의 보안 취약점을 스캔하고, 발견된 내용을 Neo4j 그래프 데이터베이스에 인덱싱하며, 잘못된 구성, 인젝션 및 공급망 위험을 탐지하기 위한 쿼리 라이브러리를 제공합니다.
RAVEN (Risk Analysis and Vulnerability Enumeration for CI/CD) 은 GitHub Actions CI 워크플로를 대규모로 스캔하고 발견된 데이터를 Neo4j 데이터베이스에 통합하도록 설계된 강력한 보안 도구입니다. Cycode 연구팀이 개발 및 유지 관리합니다.
Raven을 통해 우리는 GitHub에서 호스팅되는 가장 인기 있는 저장소 중 일부에서 보안 취약점을 식별하고 보고할 수 있었습니다. 그 예는 다음과 같습니다.
Raven을 사용하여 발견된 모든 취약점은 도구 명예의 전당에 나열했습니다.
이 도구는 잠재적인 CI/CD 취약점을 스캔하고 분석하기 위해 다음과 같은 기능을 제공합니다.
Raven의 가능한 사용 사례:
이 도구는 CI/CD 보안 분석을 위한 신뢰할 수 있고 확장 가능한 솔루션을 제공하여 사용자가 잘못된 구성을 쿼리하고 코드베이스의 보안 상태에 대한 귀중한 통찰력을 얻을 수 있도록 합니다.
지난 1년간 Cycode Labs는 CI/CD 시스템의 근본적인 보안 문제에 대해 광범위한 연구를 수행했습니다. 우리는 많은 시스템, 수천 개의 프로젝트, 그리고 여러 구성을 깊이 있게 조사했습니다. 결론은 명확합니다. 보안을 개발자에게 위임하는 모델은 실패했습니다. 이는 이전 콘텐츠에서 여러 번 입증되었습니다.
위의 각 취약점은 고유한 특성을 가지고 있어 개발자가 최신 보안 트렌드를 따라잡는 것이 거의 불가능합니다. 불행히도 각 취약점은 공통점을 공유합니다. 각 악용은 수백만 명의 피해자에게 영향을 미칠 수 있습니다.
이러한 이유로 Raven이 만들어졌습니다. CI/CD 보안 분석 워크플로(첫 번째 사용 사례로 GitHub Actions)를 위한 프레임워크입니다. 우리의 초점은 각 문제가 단독으로는 위협이 아니지만 결합되면 심각한 위협이 되는 복잡한 시나리오를 조사하는 데 있습니다.
Raven을 시작하려면 다음 설치 지침을 따르십시오.
1단계: Raven 패키지 설치```bash pip3 install raven-cycode
**Step 2**: 로컬 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
Step 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)
## 예제
모든 계정(사용자/조직)과 연관된 모든 워크플로우와 액션을 검색합니다.```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
## 속도 제한 (Rate Limiting)
효과적인 속도 제한을 위해 Github 토큰을 제공해야 합니다.
인증된 사용자의 경우 다음 속도 제한이 적용됩니다:
- 코드 검색 - 분당 30회
- 기타 API - 시간당 5000회
## 연구 지식 기반
- [Issue Injections](https://github.com/CycodeLabs/raven/blob/main/docs/Issue%20Injections/README.md)
- [Pull Request Injections](https://github.com/CycodeLabs/raven/blob/main/docs/Pull%20Request%20Injections/README.md)
- [Workflow Run Injections](https://github.com/CycodeLabs/raven/blob/main/docs/Multi%20Prerequisite%20Exploits/README.md)
- [CodeSee Injections](https://github.com/CycodeLabs/raven/blob/main/docs/Codesee%20Injections/README.md)
## 현재 제한 사항
- `Dockerfile` (없이 `action.yml`)을 참조하여 외부 액션을 실행하는 것이 가능합니다. 현재 이 동작은 지원되지 않습니다.
- `docker://...` URL을 통해 도커 컨테이너를 참조하여 외부 액션을 실행하는 것이 가능합니다. 현재 이 동작은 지원되지 않습니다.
- 로컬에서 액션을 참조하여 실행하는 것이 가능합니다. 이는 이전에 체크아웃된 다른 저장소에서 가져올 수 있으므로 복잡한 동작을 만듭니다. 현재 동작은 기존 저장소에서 찾으려고 시도합니다.
- 전체 워크플로 구조를 모델링하고 있지 않습니다. 추가 필드가 필요한 경우 [기여](https://github.com/CycodeLabs/raven/blob/main/CONTRIBUTING.md) 가이드라인에 따라 풀 리퀘스트를 제출해 주세요.
## 향후 연구 작업
- 오염 분석(Taint analysis) 구현. 예제 사용 사례 - 사용자가 풀 리퀘스트 제목(제어 가능한 매개변수)을 `data`라는 액션 매개변수에 전달할 수 있습니다. 해당 액션 매개변수는 `- run: echo ${{ inputs.data }}`와 같은 실행 명령어에서 사용될 수 있으며, 이는 코드 실행 경로를 생성합니다.
- `GITHUB_ENV`의 유해한 오용에 대한 연구 확장. 이전 오염 분석도 활용할 수 있습니다.
- `actions/github-script`가 흥미로운 위협 환경을 가지고 있는지 연구합니다. 만약 그렇다면 그래프에 모델링할 수 있습니다.
## 라이선스
[Apache License 2.0](https://github.com/CycodeLabs/raven/blob/main/LICENSE.md)
## 명예의 전당 - Raven을 사용하여 발견 및 공개된 취약점
| Name | Stars | Fix | Additional Sources |
| ------ | -------- | ---- | -------------------- |
| [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) |  | CodeSee package update, [0871341](https://github.com/freeCodeCamp/freeCodeCamp/commit/0871341c9cbf96ab455bc3e0bce636e2ef2a2be2) | [Blog](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) | [Blog](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) | [Blog](https://cycode.com/github-actions-vulnerabilities/) |
| [statelyai/xstate](https://github.com/statelyai/xstate) |  | CodeSee package update | [Blog](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) | [Blog](https://cycode.com/blog/cycode-discovers-a-supply-chain-vulnerability-in-bazel/) |
| [docker-slim/docker-slim](https://github.com/docker-slim/docker-slim) |  | CodeSee package update | [Blog](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) | [Blog](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) | [Blog](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) | [Blog](https://cycode.com/github-actions-vulnerabilities/) |
| [wireapp/wire-ios](https://github.com/wireapp/wire-ios) |  | [9d39d6c](https://github.com/wireapp/wire-ios/commit/9d39d6c93b5a58a0bc8c1aba10e0d67756359630) | [Blog](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) |  | Disabled workflow | [Blog](https://cycode.com/github-actions-vulnerabilities/) |
| [fauna/faunadb-js](https://github.com/fauna/faunadb-js) |  | [ee6f53f](https://github.com/fauna/faunadb-js/commit/ee6f53f9c985bde41976743530e3846dee058587) | [Blog](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) | [Blog](https://cycode.com/github-actions-vulnerabilities/) |
## CI/CD 보안, AppSec 및 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) 양식을 통해 데모를 요청하십시오.