A white box code scan powered by ChatGPT
ChatGPTScanner 的网页版本已经开源:https://github.com/YulinSec/ChatGPTScan-SAST
Supports:
- common vulnerabilities scan
- taint sink scan
Content below in preiew are generated by ChatGPTScan with command
python chatgptscan.py common_scan --project ./benchmark/go-sec-code --language "['go']" --include "['controllers/cmdi.go','utils']" --proxy http://127.0.0.1:7890
and
python chatgptscan.py taint_sink_scan --sink "exec.Command" --project ./benchmark/go-sec-code --language "['go']" --include "['controllers/cmdi.go','utils']" --proxy http://127.0.0.1:7890
Scan on go-sec-code
File: utils/securityUtils.go:
- No vulnerabilities found.
File: utils/gogs.go:
- No vulnerabilities found.
File: controllers/cmdi.go:
-
CommandInjectVuln1Controller.Get():
- Vulnerability: High
- The
dir
parameter is passed directly into a system command without proper input validation, which allows an attacker to inject malicious code and execute arbitrary commands on the targeted system.
-
CommandInjectVuln2Controller.Get():
- Vulnerability: High
- The
host
parameter is passed directly into a system command without proper input validation, which allows an attacker to inject malicious code and execute arbitrary commands on the targeted system.
-
CommandInjectVuln3Controller.Get():
- Vulnerability: High
- The
repoUrl
parameter is passed directly into a system command without proper input validation, which allows an attacker to inject malicious code and execute arbitrary commands on the targeted system using the${touch /tmp/pwnned}
command injection payload.
-
CommandInjectSafe1Controller.Get():
- Vulnerability: Medium
- The
dir
parameter is only checked against a whitelist but not properly sanitized, which can still allow an attacker to perform command injection if they are able to bypass or workaround the filter.
Yes, there are function call chains in the code where remote input in request can become input or parameter of exec.Command
. Here is the function call chain where a remote dir
value in the request can become input or parameter of exec.Command
in the CommandInjectVuln1Controller
controller:
c.GetString("dir")
fmt.Sprintf("ls %s", dir)
exec.Command("bash", "-c", input)
cmd.CombinedOutput()
Here is the function call chain where a remote host
value in the request can become input or parameter of exec.Command
in the CommandInjectVuln2Controller
controller:
c.Ctx.Request.Host
fmt.Sprintf("curl %s", host)
exec.Command("bash", "-c", input)
cmd.CombinedOutput()
And here is the function call chain where a remote repoUrl
value in the request can become input or parameter of exec.Command
in the CommandInjectVuln3Controller
controller:
c.GetString("repoUrl", "--upload-pack=${touch /tmp/pwnned}")
exec.Command("git", "ls-remote", repoUrl, "refs/heads/main")
cmd.CombinedOutput()
python 3.8 or above
git clone https://github.com/YulinSec/ChatGPTScanner
cd ChatGPTScanner
pip install -r requirements.txt
$ python chatgptscan.py --help
NAME
chatgptscan.py - ChatGPTScan help summary page
SYNOPSIS
chatgptscan.py - COMMAND | <flags>
DESCRIPTION
A white box code scan powered by ChatGPT
Example:
python chatgptscan.py common_scan --project ./benchmark --language "['python']" --include "['directory']" --proxy http://127.0.0.1:7890
python chatgptscan.py common_scan --project ./go-sec-code --language "['go']" --include "['controllers/cmdi.go','utils']" --proxy http://127.0.0.1:8080
python chatgptscan.py taint_sink_scan --project ./benchmark --language "['python']" --sink "os.system()" --exclude "['directory/exclude.go']"
Note:
--project path to target project
--language languages of the project, decide which file extension will be loaded
--include files send to ChatGPT, relative directory or relative filepath, match by prefix
--exclude files not send to ChatGPT, relative directory or relative filepath, match by prefix
--sink decrible your sink, only works in taint_sink_scan
--key openai api key, also get from environment variable OPENAI_API_KEY
--proxy openai api proxy
--dry dry run, not send files to ChatGPT
note: you should set your OPENAI_API_KEY first!