Skip to content
Docs

Automate your Static Application Security Testing (SAST)#

Static Application Security Testing (SAST) is a type of security testing that is run on the source code, byte code, or binary code of an application without running the application itself.

One of the most popular SAST tools is the open source tool Semgrep, which will scan your source code for vulnerabilities, secrets leakage, and other issues according to a set of rules for each supported language, outputting a list of results that can be addressed by the security team.

Chalk supports Semgrep integration out of the box, and other SAST tools can be added via the tools plugin.

Let’s see how.

Load Chalk configuration#

Make sure you have a working Installation Guide of Chalk.

Now enable the builtin SAST tools to run during build.

Terminal
chalk load https://chalkdust.io/run_sast.c4m

You can check that the configuration has been loaded by running:

Terminal
$ chalk dump

Now let’s take a look how SAST works with and without Docker.

SAST without Docker#

Grab the Caddy sources (a webserver in Go) and build it.

Terminal
git clone https://github.com/caddyserver/caddy
cd caddy
go build ./cmd/caddy

Now run chalk insert ./caddy to Chalk the binary.

Terminal
$ chalk insert ./caddy > /dev/null
info:  attestation: signing file /home/admin/caddy/caddy
info:  /home/admin/caddy/caddy: chalk mark successfully added
info:  /home/admin/.local/chalk/chalk.log: Open (sink conf='default_out')
info:  Full chalk report appended to: ~/.local/chalk/chalk.log

The SAST report is included in the report generated by chalk insert. We can extract it with jq.

Terminal
jq -c -r '.[]|.SAST.semgrep' ~/.local/chalk/chalk.log | tail -n1 > sast.json

The Semgrep output is deeply nested so a jq query to pretty-print the results is gnarly, but you can use this as a starting point.

Terminal
$ jq -r '.runs[]|.results[]|[.message.text[0:40], "...", (.locations[]|.physicalLocation.artifactLocation.uri[-25:]), ":", (.locations[]|.physicalLocation.region.snippet.text[0:40]|split("\n")[0])] | join (" ")' sast.json | head -n 10
Using variable interpolation `${{...}}`  ... lows/release-proposal.yml :         run: |
Using variable interpolation `${{...}}`  ... lows/release-proposal.yml :         run: |
Using variable interpolation `${{...}}`  ... lows/release-proposal.yml :         run: |
Using variable interpolation `${{...}}`  ... lows/release-proposal.yml :         run: |
Detected directly writing or similar in  ... home/admin/caddy/admin.go :                _, err = w.Write(buf.Bytes())
Insecure WebSocket Detected. WebSocket S ... ttpcaddyfile/addresses.go :                return nil, fmt.Errorf("the scheme ws:
`MinVersion` is missing from this TLS co ... caddyconfig/httploader.go :                        tlsConfig = &tls.Config{Certificates:
`MinVersion` is missing from this TLS co ... caddyconfig/httploader.go :                        tlsConfig = &tls.Config{Certificates:
`MinVersion` is missing from this TLS co ... caddyconfig/httploader.go :                                tlsConfig = new(tls.Config)
Detected directly writing or similar in  ... caddy/caddyconfig/load.go :                        _, _ = w.Write(respBody) //nolint:gos

Embedding the SAST report#

While we could also embed the SAST report into the binary like we can with SBOM reports, you should think carefully about doing this. You don’t want to ship your binary along with a list of vulnerabilities.

If you have a good reason to embed the SAST report you can do so by loading:

Terminal
chalk load https://chalkdust.io/embed_sast.c4m

Now let’s take a look at generating SAST reports from Chalk for Docker images.

SAST with Docker#

Things are a little different in Docker world. First off we cannot use chalk insert to inject a container because containers are immutable. Instead, Chalk wraps Docker build commands and injects Chalk marks into the container during the build process.

Let’s build Curl via Docker and view its SAST report.

Curl sources#

First, grab the Curl sources.

Terminal
cd ~
git clone https://github.com/curl/curl
cd curl

Now build the image with Chalk.

Terminal
chalk docker build .

Chalk will generate a build report when we do this which will include the SAST report. We can extract the SAST report with jq.

Terminal
jq -c -r '.[]|.SAST.semgrep' ~/.local/chalk/chalk.log | tail -n1 > sast.json

And we can pretty-print the SAST JSON report with jq.

Terminal
$ jq -r '.runs[]|.results[]|[.message.text[0:40], "...", (.locations[]|.physicalLocation.artifactLocation.uri[-25:]), ":", (.locations[]|.physicalLocation.region.snippet.text[0:40]|split("\n")[0])] | join (" ")' sast.json | head -n 10
Insecure WebSocket Detected. WebSocket S ... cs/internals/WEBSOCKET.md : using the `ws://` or `wss://` URL scheme
Insecure WebSocket Detected. WebSocket S ... cs/internals/WEBSOCKET.md : If the given WebSocket URL (using `ws://
Insecure WebSocket Detected. WebSocket S ... pts/CURLOPT_WS_OPTIONS.md :     curl_easy_setopt(curl, CURLOPT_URL,
The special variable IFS affects how spl ... jects/OS400/initscript.sh :         IFS="/"
The special variable IFS affects how spl ... jects/OS400/initscript.sh :         do      IFS="${IFSSAVE}"
The special variable IFS affects how spl ... jects/OS400/initscript.sh :         IFS="${IFSSAVE}"

And this might not look like it’s reporting anything meaningful but this is indeed what you’d get if you run semgrep scan --config auto on the Curl repo. Curl is in good shape!