Find vulnerability status from Git repository URL, Git branch/commit, and CVE ID
gvs-demo.mp4
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,jqandmake -
Gemini API credentials (optional)
If Gemini credentials are absent, the
Summaryfield in the final JSON result will be an error message.- Create a file named
~/.gemini.conf - Use the below contents
API_URL=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent API_KEY=<your-api-key>
- Create a file named
$ git clone https://github.com/k37y/gvs && cd gvs
$ make image-run$ 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"
]
}
}
}The scanner supports both branch names and commit hashes for repository analysis:
# API request with branch name
{
"repo": "https://github.com/example/repo",
"branchOrCommit": "main", # ← Branch name
"cve": "CVE-2024-45339"
}# API request with commit hash
{
"repo": "https://github.com/example/repo",
"branchOrCommit": "abc123f", # ← Commit hash (7+ hex characters)
"cve": "CVE-2024-45339"
}- Branch Detection: Names containing non-hex characters (e.g.,
main,feature/test,release-4.18) - Commit Detection: 7-40 character strings containing only hexadecimal characters (0-9, a-f, A-F)
- Performance: Branch cloning uses
--depth 1for speed, commit cloning uses full history to ensure commit accessibility
| Input | Detected As | Clone Method |
|---|---|---|
main |
Branch | git clone --depth 1 --branch main |
feature/auth |
Branch | git clone --depth 1 --branch feature/auth |
abc123f |
Commit | git clone → git checkout abc123f |
1a2b3c4d5e6f7a8b |
Commit | git clone → git checkout 1a2b3c4d5e6f7a8b |
The scanner supports multiple call graph algorithms, configurable via the ALGO environment variable:
| Algorithm | Speed | Precision | Description | Use Case |
|---|---|---|---|---|
vta (default) |
Slowest | Highest | Variable Type Analysis | When accuracy is critical |
rta |
Medium | Good | Rapid Type Analysis | Balanced performance |
cha |
Fast | Lower | Class Hierarchy Analysis | Large codebases where speed matters |
static |
Fastest | Lowest | Static analysis (direct calls only) | Quick scans |
# Example: Use Rapid Type Analysis for better performance
export ALGO=rta
make image-run
# Example: Use algorithm directly with cg binary
./bin/cg -algo rta CVE-2024-45338 /path/to/repo
./bin/cg -algo=static CVE-2024-45338 /path/to/repo
# Combine with other flags
./bin/cg -fix -algo cha CVE-2024-45338 /path/to/repo
# Get help
./bin/cg -hPORTspecifies the port on which the application will runWORKER_COUNTsets the size of the worker pool used to process endpoint and symbol combinations (optional)ALGOsets the call graph analysis algorithm: vta, rta, cha, static (optional, defaults to vta)
Each parameter is independent and can be set or omitted as needed:
# Build with all parameters
make image-run PORT=8082 WORKER_COUNT=3 ALGO=rta
# Build with only worker count
make image-run WORKER_COUNT=5
# Build with only algorithm choice
make image-run ALGO=static
# Build with defaults (vta algorithm, auto worker count)
make image-run$ go install github.com/k37y/gvs/cmd/gvs@main
$ go install github.com/k37y/gvs/cmd/cg@main
- Type (string) All 14 possible values:
"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
- Confidence (string) 3 possible values:
"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
- Location (string)
Format: "filepath:line:column"
Example: "/path/to/file.go:123:45"
- Evidence ([]string) Possible values (examples from code):
["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"]
- Symbol (string) Possible values:
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"
- Package (string) Values: The package being analyzed (passed as parameter)
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.
