How it works
During each CI build, the repository source code is volumed into the Salus container and Salus begins executing. An individual scanner might conduct static analysis, dependency checks, anti-pattern (e.g. grep) checks, or anything else that improves security.
To update a scanner or experiment with new scanners, we update the Salus container. Since each CI build pulls and runs the latest container, all builds immediately inherit these changes. If issue are found, the build fails and the scanner’s output is shown to the developer immediately so that they can self service their fix.
###### Salus Scan v1.0.0 for engineering/proxy ######
BundleAudit => passed
PatternSearch => failed
Forbidden pattern in public/offline.html:204:
<p>We are currently offline - <br/>
<a href="https://status.internal.net">status page</a>
Use `link_to('<link>', target: '_blank')` for rendering links so
that the appropriate security features can be applied.
overall => failed
Salus also compiles reports about the results of each scanner and which dependencies are being used by a project. At Coinbase, we consume these reports into our logging pipeline to allow us to quickly identify which projects might be using a package that recently had a vulnerability released and from there, we can efficiently move into incident response mode.
Screenshot of Kibana displaying the results of Salus scans.
Salus can be run out of the box with strong default configuration but also support powerful customization to ensure that you can pick which scanners will run, which scanner will fail builds when finding issues, and where to send reports. We use this functionality at Coinbase so that we can enforce a global security policy for all projects, but also apply special configuration at the repository level if a certain project needs it.
For local customization, multiple configuration files can be concatenated. For example, if a project’s dependency is carrying a CVE with no available patch and we have confirmed that the vulnerability is not exploitable, we can use a local configuration file to ignore this concern.
docker run \
--rm \
-v $(pwd):/home/repo \
coinbase/salus --config "https://salus-config.internal.net/salus-global.yaml file://local-salus-config.yaml"
Pointing to remote configuration files also allows a security team to introduce new security policies into an organization and identify where there are gaps without failing builds and surprising developers. A scanner can run in soft mode, Salus will provide data on repos that are not compliant, and then those projects can be patched before enforcing a new, higher global security policy.
Salus currently runs the following checks:
CVE checks for Ruby gems and Node modules via BundleAudit and NSP respectively.
Brakeman for Ruby on Rails vulnerabilities.
Reports which Ruby gems, Node modules, Go packages and Python packages are used by the repo.
Pattern matching on regular expressions of your choice — for example, this could look for the use of poor cryptographic primitives or potentially dangerous code like React’s dangerouslySetInnerHTML.