Last month, we released the industry’s first integrated security analyzer for Go. Now that it has been available for a few weeks, I thought it would be helpful to provide some detail about how the Contrast agent actually works, what it finds, and how it can help software developers.
What the Contrast Go Agent Delivers
Placing the Contrast agent into an application or microservice can help developers evaluate the security of their Go code as it is being tested. Just like when using agents for application performance management (APM), there are no forms to fill out and no special security tests to run in order to gain additional insights. The agent monitors application programming interface (API) execution from inside the code, which is more accurate than other technical approaches—such as traditional static application security testing (SAST) and dynamic application security testing (DAST)—and requires far less work than manual approaches (such as penetration testing). While not a full substitute for human security testing, instrumentation-based agents help developers reduce the need for security team analysis of testing results, which can bottleneck development processes and cause delays.
Exploring Specific Details Regarding the Contrast Go Agent
Following are some of the particulars that you need to know about the Contrast Go agent:
What types of applications are most suited?
This new Contrast agent is suited for web applications and web-accessible microservices written in Go. It is not applicable for command-line interface (CLI) or host-based tools like the Docker environment manager.
How does the Contrast Go agent function within a development pipeline?
Teams should integrate the Contrast agent into the build phase of continuous integration/continuous deployment (CI/CD) in two separate jobs. The first job will build a security-aware binary for use in test environments; the second job will build a standard binary from the same source revision for production.
How does the Contrast Go agent work “under the hood”?
There are two main components involved in installing the Contrast agent. The agent itself is simply a Go package—“contrast-go” adds sensors at build time similar to the way that “go test -cover” works in the core Go toolchain.
In order to inject the agent package into an application and its dependencies, “contrast-go” acts as a wrapper to “go” itself. Where one might normally run “go build,” they would instead run “contrast-go build.”
It’s important to think of the “go” command as a build tool like CMake. Its job is to inspect source code and the go.mod file to figure out which packages need to be compiled and linked together into an executable. The “go” command then spawns the compiler, linker, and any other necessary tools to do whatever needs to be done. For example, if “go” sees that the “fmt” package needs to be compiled, it will find all of the source code files of the “fmt” package and pass these along to the compiler in order to create the object that ends up in an executable.
Sometimes, “go” will seek to make changes or additions to a package’s source code before it invokes the compiler. When someone asks for code coverage in tests, “go” will add counters to the package’s source code before compiling it. Then, as it runs, the code will do everything it normally would—but it will also increment these counters so that the test runner can know exactly which parts of the code ran.
When “contrast-go” wraps the “go” command, it simply takes the source code for the packages that will be compiled and updates it to import the agent package. It then updates the source code further (but not files) to add calls into the agent package adjacent to the code that Contrast wants to instrument. The original source code remains intact, because “contrast-go” can see everything it needs to by simply adding these agent package calls before and after important events in the code, such as function calls. By being part of the running executable, the Contrast agent is able to see relevant runtime events and detect vulnerabilities accurately.
With all of this in place, the Contrast agent will do some initialization (such as reading its configuration and setting up reporting) as soon as the application starts up. It then sits back and lets the application code run as it normally would—using the hooks added at build time to see what it needs to and reporting when a vulnerability is discovered. Any other tests done on the instrumented code represent a test of the application, plus an additional security assessment.
How does this impact compatibility?
As to the question, “How does this impact compatibility?” The answer is, “It doesn’t.”
During the Go agent’s design process, our primary concern was for the application to run exactly as it does without the agent—the only change would be the sensors. We continue to maintain a variety of test suites across different Go versions to ensure that tests run and deliver the same result, both with and without the agent embedded. While some test suites are custom, many come from different projects across Go communities, including projects that do not meet the most-suited criteria described above. The only difference is a slight impact to time and resources. Sensors are added at the beginning and end of different methods. The rest of the code is functionally equivalent.
What is the impact of the Contrast Go agent on performance?
As to the impact of the Contrast Go agent on performance, the impact is minimal and limited to test environments. Within testing, the performance trade-off of using security-aware binaries can be measured in milliseconds. But when security is not a part of the development cycle, that impact is most often in dollars (e.g., the financial damages incurred from exploitation of unremediated vulnerabilities that pass into production).
In production and performance-testing environments, developers should build a new binary without security sensors.
Try the New Go Agent
We are excited for everyone to try out Contrast’s new agent for Go. It is a great addition to our suite of existing agents for Java, .NET/.NET Core, Python, Node, and Ruby. If you have questions, feel free to reach out to us through your standard support channel.
Inside AppSec Podcast: Modern Application Security Now Available for Golang Applications
Blog Post: Secure Coding With Go