k37y/gvs

GitHub: k37y/gvs

gvs 是一款 Go 代码漏洞分析工具,通过调用图算法精确判断指定 Git 仓库是否实际受到特定 CVE 的影响。

Stars: 4 | Forks: 6

[![Go](https://img.shields.io/badge/Go-1.23+-00ADD8?logo=go&logoColor=white)](https://go.dev) [![License](https://img.shields.io/github/license/k37y/gvs)](https://github.com/k37y/gvs/blob/main/LICENSE) [![Go Report Card](https://goreportcard.com/badge/github.com/k37y/gvs)](https://goreportcard.com/report/github.com/k37y/gvs) ![API Hits](https://img.shields.io/endpoint?url=https://gvs-counter.kevy.workers.dev/badge&label=API%20Hits) ![gvs](https://static.pigsec.cn/wp-content/uploads/repos/cas/37/37619d70ba04c2f94a258c1d3f14a25ff249b313e179ae9030530f1206396c3a.png) 从 **Git 仓库 URL**、**Git 分支/提交** 和 **CVE ID** 查找漏洞状态 ## 演示 1 [!demo-1](https://github.com/user-attachments/assets/3b013256-368f-45b1-8cd3-897173a48814) ## 演示 2 [![demo-2](https://asciinema.org/a/721319.svg)](https://asciinema.org/a/721319) ## 流程图 ``` flowchart TD A[Start: Input Parameters] --> B[Clone Repository] B --> C[Checkout Branch or Commit ID] C --> D[Find Project Endpoint Files] D --> E[Find Affected Symbols from CVE ID] E --> F[Generate Endpoint-Symbol Combinations] F --> G[Loop: For Each Combination] G --> H[Generate Callgraph Path] H --> I{Is Symbol Used in Endpoint?} I -- Yes --> J[Compare Used vs Fixed Version] J --> K{Used Version < Fixed?} K -- Yes --> L[Mark as Vulnerable] K -- No --> M[Mark as Not Vulnerable] L --> N[Add to Result] M --> N I -- No --> O[Skip Combination] O --> N N --> P{More Combinations?} P -- Yes --> G P -- No --> Q[Generate Summary Using AI - Optional] Q --> R[Return Result as JSON] R --> S[End] %% Style nodes style A fill:#458588,stroke:#282828,stroke-width:1px,color:#ebdbb2 style B fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style C fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style D fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style E fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style F fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style G fill:#689d6a,stroke:#282828,stroke-width:1px,color:#ebdbb2 style H fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style I fill:#d79921,stroke:#282828,stroke-width:1px,color:#282828 style J fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style K fill:#d79921,stroke:#282828,stroke-width:1px,color:#282828 style L fill:#fe8019,stroke:#282828,stroke-width:1px,color:#282828 style M fill:#98971a,stroke:#282828,stroke-width:1px,color:#ebdbb2 style N fill:#689d6a,stroke:#282828,stroke-width:1px,color:#ebdbb2 style O fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style P fill:#d79921,stroke:#282828,stroke-width:1px,color:#282828 style Q fill:#b16286,stroke:#282828,stroke-width:1px,color:#ebdbb2 style R fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 style S fill:#458588,stroke:#282828,stroke-width:1px,color:#ebdbb2 linkStyle 18 stroke-width:1px,stroke-dasharray:5,5 %% style white fill:#ebdbb2,stroke:#282828,stroke-width:1px,color:#282828 %% style orange fill:#fe8019,stroke:#282828,stroke-width:1px,color:#282828 %% style green fill:#98971a,stroke:#282828,stroke-width:1px,color:#ebdbb2 %% style blue fill:#458588,stroke:#282828,stroke-width:1px,color:#ebdbb2 %% style magenta fill:#b16286,stroke:#282828,stroke-width:1px,color:#ebdbb2 %% style cyan fill:#689d6a,stroke:#282828,stroke-width:1px,color:#ebdbb2 %% style yellow fill:#d79921,stroke:#282828,stroke-width:1px,color:#282828 ``` ## 前置条件 * `podman`、`git`、`jq` 和 `make` * Gemini API 凭证(可选) 如果缺少 Gemini 凭证,最终 JSON 结果中的 `Summary` 字段将是一条错误信息。 - 创建一个名为 `~/.gemini.conf` 的文件 - 使用以下内容 API_URL=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent API_KEY= ## 用法 ### 构建并作为容器镜像运行 ``` $ git clone https://github.com/k37y/gvs && cd gvs $ make image-run ``` ### Callgraph 路径的 API 请求和响应示例 ``` $ curl --request POST \ --header "Content-Type: application/json" \ --data '{"repo": "https://github.com/k37y/gvs-example-one", "branch": "main", "cve": "CVE-2024-45338"}' \ http://localhost:8082/callgraph | jq . ``` ``` { "taskId": "1748493013100462517" } ``` ``` $ curl --silent \ --request POST \ --header "Content-Type: application/json" \ --data '{"taskId":"1748493013100462517"}' \ http://localhost:8082/status | jq .output ``` ``` { "AffectedImports": { "golang.org/x/net/html": { "FixedVersion": [ "v0.33.0" ], "Symbols": [ "Parse", "ParseFragment", "ParseFragmentWithOptions", "ParseWithOptions", "htmlIntegrationPoint", "inBodyIM", "inTableIM", "parseDoctype" ], "Type": "non-stdlib" } }, "Branch": "main", "CVE": "CVE-2024-45338", "Directory": "/tmp/cg-gvs-example-one-2212737432", "Errors": null, "Files": { ".": [ [ "main.go" ] ] }, "GoCVE": "GO-2024-3333", "IsVulnerable": "true", "Repository": "https://github.com/k37y/gvs-example-one", "Summary": "## Vulnerability Report Summary The project is vulnerable to CVE-2024-45338 (GO-2024-3333) due to the use of `golang.org/x/net/html` at version `v0.23.0`. The following symbols from the `golang.org/x/net/html` package are used in the codebase: `Parse`, `ParseWithOptions`, `htmlIntegrationPoint`, `inBodyIM`, `inTableIM`, and `parseDoctype`. To remediate this vulnerability, update `golang.org/x/net/html` to version `v0.24.0` or higher. The recommended fix commands are: go mod edit -replace=golang.org/x/net=golang.org/x/net@v0.33.0 go mod tidy go mod vendor No errors or issues were encountered during the scanning process. ", "UsedImports": { "golang.org/x/net/html": { "CurrentVersion": "v0.23.0", "FixCommands": [ "go mod edit -replace=golang.org/x/net=golang.org/x/net@v0.33.0", "go mod tidy", "go mod vendor" ], "ReplaceVersion": "v0.24.0", "Symbols": [ "Parse", "ParseWithOptions", "htmlIntegrationPoint", "inBodyIM", "inTableIM", "parseDoctype" ] } } } ``` ## 分支和提交支持 扫描器支持用于仓库分析的**分支名称**和**提交哈希**: ### 使用分支名称 ``` # 带 branch name 的 API request { "repo": "https://github.com/example/repo", "branchOrCommit": "main", # ← Branch name "cve": "CVE-2024-45339" } ``` ### 使用提交哈希 ``` # 带 commit hash 的 API request { "repo": "https://github.com/example/repo", "branchOrCommit": "abc123f", # ← Commit hash (7+ hex characters) "cve": "CVE-2024-45339" } ``` ### 工作原理 - **分支检测**:包含非十六进制字符的名称(例如,`main`、`feature/test`、`release-4.18`) - **提交检测**:仅包含十六进制字符(0-9、a-f、A-F)的 7-40 个字符的字符串 - **性能**:分支克隆使用 `--depth 1` 以提高速度,提交克隆使用完整历史记录以确保提交可访问性 ### 示例 | 输入 | 检测为 | 克隆方法 | |-------|-------------|--------------| | `main` | 分支 | `git clone --depth 1 --branch main` | | `feature/auth` | 分支 | `git clone --depth 1 --branch feature/auth` | | `abc123f` | 提交 | `git clone` → `git checkout abc123f` | | `1a2b3c4d5e6f7a8b` | 提交 | `git clone` → `git checkout 1a2b3c4d5e6f7a8b` | ## 高级用法 ### Call Graph 算法配置 扫描器支持多种 Call Graph 算法,可通过 `ALGO` 环境变量进行配置: | 算法 | 速度 | 精度 | 描述 | 用例 | |-----------|-------|-----------|-------------|----------| | `vta`(默认) | 最慢 | 最高 | 变量类型分析 | 当准确性至关重要时 | | `rta` | 中等 | 良好 | 快速类型分析 | 平衡的性能 | | `cha` | 快速 | 较低 | 类层次结构分析 | 速度优先的大型代码库 | | `static` | 最快 | 最低 | 静态分析(仅限直接调用) | 快速扫描 | ``` # 示例:使用 Rapid Type Analysis 获得更好的性能 export ALGO=rta make image-run # 示例:直接使用 algorithm 和 cg binary ./bin/cg -algo rta CVE-2024-45338 /path/to/repo ./bin/cg -algo=static CVE-2024-45338 /path/to/repo # 与其他 flags 结合使用 ./bin/cg -fix -algo cha CVE-2024-45338 /path/to/repo # 获取帮助 ./bin/cg -h ``` ### 构建自定义容器镜像 * `PORT` 指定应用程序运行的端口 * `WORKER_COUNT` 设置用于处理 endpoint 和 symbol 组合的 worker 池大小(可选) * `ALGO` 设置 Call Graph 分析算法:vta、rta、cha、static(可选,默认为 vta) 每个参数都是独立的,可根据需要设置或省略: ``` # 使用所有 parameters 构建 make image-run PORT=8082 WORKER_COUNT=3 ALGO=rta # 仅使用 worker count 构建 make image-run WORKER_COUNT=5 # 仅使用 algorithm 选择构建 make image-run ALGO=static # 使用默认值(vta algorithm,自动 worker count)构建 make image-run ``` ### 作为二进制文件安装 ``` $ go install github.com/k37y/gvs/cmd/gvs@main $ go install github.com/k37y/gvs/cmd/cg@main ``` ### ReflectionRisks 1. Type (string) 所有 14 个可能的值: ``` "value_of" - reflect.ValueOf() usage "method_by_name" - obj.MethodByName() calls "type_method_by_name" - Type.MethodByName() calls "call_slice" - Variadic function calls via reflection "method_by_index" - Method(i) calls by index "field_by_name" - FieldByName() calls "indirect" - reflect.Indirect() calls "new_at" - reflect.NewAt() calls (unsafe) "convert" - Type conversion via reflection "interface" - Interface() conversion calls "function_registry" - Function maps/registries "string_literal" - String literals with vulnerable symbols "reflection_assignment" - Assignments involving reflection "selector_access" - Direct field/method access ``` 2. Confidence (string) 3 个可能的值: ``` "high" - Used for: value_of, method_by_name, call_slice, new_at "medium" - Used for: type_method_by_name, method_by_index, field_by_name, indirect, interface, function_registry, reflection_assignment "low" - Used for: convert, string_literal, selector_access ``` 3. Location (string) ``` Format: "filepath:line:column" Example: "/path/to/file.go:123:45" ``` 4. Evidence ([]string) 可能的值(代码示例): ``` ["reflect.ValueOf(symbolName)"] ["MethodByName(\"methodName\")"] ["Type.MethodByName(\"methodName\")"] ["CallSlice with symbolName"] ["Method call by index - potential vulnerable symbol"] ["FieldByName(\"fieldName\")"] ["reflect.Indirect - potential vulnerable symbol access"] ["reflect.NewAt - unsafe pointer creation"] ["Type conversion - potential symbol access"] ["Interface() conversion - potential symbol access"] ["Function registry with vulnerable symbols"] ["String literal: \"literalValue\""] ["Assignment involving reflection - potential symbol storage"] ["Direct access to symbolName"] ``` 5. Symbol (string) 可能的值: ``` Actual vulnerable symbols: Any symbol from the CVE (e.g., "Do", "Client.Do", "RoundTrip") Generic identifiers: "reflection_assignment" "method_by_index" "indirect_access" "unsafe_new_at" "type_convert" "interface_convert" "function_registry" ``` 6. Package (string) 值:正在分析的 package(作为参数传递) ``` Examples: "net/http", "golang.org/x/net/http2", "main", etc. The values are determined by the specific vulnerability symbols being searched for and the package context where the reflection usage is detected. ```
标签:AI, EVTX分析, Go, Ruby工具, 代码安全, 文档安全, 日志审计, 漏洞枚举, 网络测绘, 自动化代码审查, 请求拦截, 错误基检测, 静态代码分析