/jul 1, 2024

The Veracode CLI: End to End Testing with Static, Container, and Dynamic Scanning

By Robert Haynes

In this blog, we’re going to examine the Veracode CLI tool. Available for Windows, MacOS, and Linux, the imaginatively named binary veracode can perform a variety of functions across the SDLC.

Installing the tool is easy, just follow the steps in the documentation. Once installed, you can explore all the cli the functions yourself using:

veracode help

To get started, you’ll need to configure the authentication using:

veracode configure

You need to input your Veracode API ID and API secret (you can generate these in the Veracode Web UI or using API calls).

Assuming we have some application code, the most obvious first step might be to perform a Static Analysis scan. To get the most accurate results, Veracode scans deployment artifacts, rather than source code (there are some really good reasons for this that are beyond the scope of this blog).  So the first job is to package the code for scanning.

In our example, we’re going to use a demo Java application called verademo. It's freely available to clone if you's like to follow along with this example. 

To package the  code for scanning use the package subcommand and specify the source and output folders:

veracode package --source ./verademo --output ./verademo
This creates an archive file in the specified output folder called verademo.wa that has been packed correctly for Veracode to perform a static analysis on the artifact. Scanning is initiated using the veracode static command:
veracode static scan ./verademo/verademo.war --results-file ./verademo/results.json

This will upload the code to Veracode, perform the scan, and then return results to the results.json file. There are also options to specify a particular profile ID to use, to specify a baseline file, and several other options. To see them all, use:

veracode static scan --help

The command also outputs results to the terminal grouped by severity, along with an (unsurprising) message that the scan has failed policy. 


CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'): com/veracode/verademo/controller/UserController.java:165

You can see from the output that the results contain the CWE ID, the path to the source code, and the line number with the flaw, making it easy to find. 

The next obvious step might be to try and correct some of these flaws. This is where Veracode Fix comes into play. Taking the example output above we can see what solutions Fix can offer us for the problems in UserController.java.

To do this we use the veracode fix subcommand with the full path to the file and the results file:

veracode fix –––./verademo/app/src/main/java/com/veracode/verademo/controller/UserController.java --results ./verademo/results.json

This will output all the detected CWE’s and prompt us to select one to address. Picking issue 1 will result in Veracode Fix supplying a proposed solution to apply and displaying the fixes in a 'diff' style syntax. Fix will supply up to three solutions to pick from (in this example there is only 1 viable solution) and prompt for the fix to apply. The remediation is applied directly to the code, which can then be committed back to a source control system, or repackaged and rescanned for additional flaws (only one remediation should be applied to any single source file at a time)

If you’d rather code this into some kind of automated system, fix also offers an  --apply option whereby you supply the source code file, the results file, and the issue ID  (as --issue-id) extracted from the results.json file. Extracting the Issue ID is best done programmatically, and some sample python code to do this is available.


python ./extract.py ./verademo/results.json UserController.java

Findings for source File: UserController.java


Issue ID, CWE ID

(1029, '89')


To apply the first suggested fix for this issue to the file use:

./verademo/app/src/main/java/com/veracode/verademo/controller/UserController.java --results ./verademo/results.json --apply --issue-id 1029


Veracode Fix

Version VERACODE_CLI_2.14.0

Processing file ./verademo/app/src/main/java/com/veracode/verademo/controller/UserController.java

Request submitted with projectId: 31483f72-dc88-4f90-9647-7c85413fe008

Applying fix 1...

Now we have resolved that issue, we can go on and resolve other issues in the file (there is also a --type directory  flag we can use to resolve all possible flaws within a project).

Once this work is complete, we might want to build a container from the project to run the app. The repo includes a Dockerfile and instructions to build the app.

But is our resulting container secure? To find out we can use veracode scan to assess the container image.

veracode scan --source <your dockerhub ID>/verademo:latest --type image --format table

This is going to give us a table output of the (many) things wrong with the container image, including CVE’s for the base image components, problems with the Dockerfile etc.

NAME                  INSTALLED      FIXED-IN       TYPE          VULNERABILITY     SEVERITY

commons-compress      1.19          1.26.0         java-archive   GHSA-4g9r-vxhx-9pgx  High       

Let’s assume we fix all our issues, and now we want to run the container as a web app. To run the container on an AWS service, for example, we might want to use an AWS CloudFormation Template to automate the deployment. Not being Infrastrucure as Code experts, we did a Google search and found an example on GitHub. But will it be a secure configuration? Let’s find out.

veracode scan can also scan several IaC file formats:

veracode scan --source ./fargate-cloudformation-example --type directory --format table

This CFT seems to have some problems:

No vulnerabilities found


TITLE                                                 PROVIDER   ID              SEVERITY

CloudWatch log groups should be encrypted using CMK   AWS        AVD-AWS-0017    LOW       

ECS clusters should have container insights enabled   AWS        AVD-AWS-0034    LOW       

An outdated SSL policy is in use by a load balancer.  AWS        AVD-AWS-0047    CRITICAL  

Load balancers should drop invalid headers            AWS        AVD-AWS-0052    HIGH      

Load balancer is exposed to the internet.             AWS        AVD-AWS-0053    HIGH      

An ingress security group rule allows traffic from /0. AWS        AVD-AWS-0107    CRITICAL  

Missing description for security group rule.          AWS        AVD-AWS-0124    LOW       

Missing description for security group rule.          AWS        AVD-AWS-0124    LOW       

No secrets found

Policy Results

TYPE       MESSAGE                                                                         

Config Found CRITICAL issues in infrastructure as code: fargate.yaml: An ingress        

           security group rule allows traffic from /0.                                       

Config Found CRITICAL issues in infrastructure as code: fargate.yaml: An outdated SSL   

           policy is in use by a load balancer.                                             

Config Found HIGH issues in infrastructure as code: fargate.yaml: Load balancer is      

           exposed to the internet.                                                         

Config Found HIGH issues in infrastructure as code: fargate.yaml: Load balancers should 

           drop invalid headers                                                             

Policy Passed = false

Since we’re keen just to get this app up and running so we can test it it seemed easier to just run it locally and expose it to the world using ngrok to create an ephemeral https URL for our container.

Now with a running app, it’s time to scan with Veracode DAST Essentials. While the initial DAST configuration is easiest to do via the Veracode platform UI, subsequent scans can now be done via the veracode CLI using a webhook ID that the platform creates for each target.

In our example, the webhook UUID is 7af15ee0-ad6e-4aba-b1db-2f727169c980. 

veracode dynamic scan --webhook 7af15ee0-ad6e-4aba-b1db-2f727169c980

Since the default is to fail on any findings, including informational it might be  better to add a --fail-on-severity modifier to specify what level of issues to fail on, e.g.

veracode dynamic scan --webhook 7af15ee0-ad6e-4aba-b1db-2f727169c980 --fail-on-severity high

The command outputs the progress of the scan (which can also be tracked within the platform and by using the veracode dynamic status command), then the results, and finally the scan status:

9:58AM ERR Failing due to severity threshold: high

This is hardly surprising given the many uncorrected flaws and problems that the other scan types have reported!


In this blog we have used the Veracode CLI to:


Related Posts

By Robert Haynes

Robert’s quarter-century working in IT has progressed (or is that regressed?) through helpdesk, UNIX sysadmin, backup, storage, application security,  technical sales, and marketing.  He now spends his time hanging out at the intersection of artificial intelligence and human ingenuity, waving a sign that says: “This way for secure software."