Project: secureCodeBox (Provisioning / Security & Compliance)
File: 2021-10-27-sast-scanning.md

title: Introducing SAST Scanning With secureCodeBox 3.3 author: Max Maass author_title: Core Developer author_url: https://github.com/malexmave authorimageurl: https://avatars.githubusercontent.com/u/1688580?v=4 tags: secureCodeBox SAST cascading scans case study description: This post gives an introduction to using the new SAST functionality of secureCodeBox to find a malicious dependency image: /img/blog/2021-10-27-magnifyingglass.jpg Cover photo by on . With secureCodeBox 3.3, we have added several features that allow you to use secureCodeBox for static application security testing (SAST). This blog post gives an introduction to how several new features of secureCodeBox 3.3 can be used to quickly run targeted SAST scans of your entire codebase. By the end of this post, you will know how to build a SAST workflow to detect which of your repositories include a malicious dependency. We will cover all steps of the process: obtaining a list of all software repositories in your organization, cloning and scanning them, and even dropping all of the results into a DefectDojo instance for later inspection. <!--truncate--> secureCodeBox has been able to run dynamic security tests of your infrastructure for quite a while. However, some issues are easier to catch by analyzing the source code of the applications directly. This is the domain of static application security testing (SAST) tools, which detect dangerous code fragments and inform you long before they hit your production systems. Normally, you would integrate these tools directly into your continuous integration (CI) workflows, so that the warnings reach the developers directly. However, in some cases, you may also want to automatically analyze all repositories of your organization from a central location. For example: You may want to find out which repositories use a specific API that you want to deprecate, check if any projects include a vulnerable () version of a library, or perform a variant analysis to determine if a newly detected critical security issue is present in other repositories. In these cases, having your security team run a single, automated scan over all repositories can be easier than approaching every single development team individually. Let us imagine you are a security specialist at a software company. You wake up to the news that the popular JavaScript library . Of course, you let your colleagues know immediately, but now you are wondering: is any of the software in our code repositories actually using the affected version of the library? Let's find out! In total, we need to perform three steps: Identify all Git repositories in your organization. Clone each repository and check if they are using an affected version of the library. Make the results available for inspection. For the purpose of this article, we will assume that you are using either GitHub or Gitlab to manage your source code repositories, and that you have (at the very least) read access to them. If this is the case, you can use the existing to generate a list of all repositories in your organization. For example, you can find all repositories under the secureCodeBox GitHub organization like this: ```yaml apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: name: "scan-github" spec: scanType: "git-repo-scanner" parameters: "--git-type" "github" "--access-token" "$(GITHUB_TOKEN)" "--organization" "secureCodeBox" "--annotate-latest-commit-id" "True" cascades: matchLabels: securecodebox.io/intensive: medium securecodebox.io/invasive: non-invasive env: name: GITHUB_TOKEN valueFrom: secretKeyRef: name: github-access-token key: token ``` This example assumes that you have created a GitHub with the `repo` scope and loaded it as a Kubernetes secret named `github-access-token`. To do the latter, run: ```bash echo -n 'gh_abcdef...' > github-token.txt # use -n to avoid trailing line break kubectl create secret generic github-access-token --from-file=token=github-token.txt rm

``` And that's it! In this example, the scanner will automatically find all repositories under the secureCodeBox GitHub organization that you have access to, and generate a JSON output that looks something like this: ```json [ { "name": "GitHub Repo", "description": "A GitHub repository", "category": "Git Repository", "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { "id": "292293538", "web_url": "https://github.com/secureCodeBox/documentation", "full_name": "secureCodeBox/documentation", "owner_type": "Organization", "owner_id": "34573705", "owner_name": "secureCodeBox", "created_at": "2020-09-02T13:39:10Z", "lastactivityat": "2021-10-26T11:23:25Z", "visibility": "public", "lastcommitid": "106a70b63fe9ffd6b2b264352331fc5e7d7821f0" }, "id": "37c49e64-0f12-40ec-9e51-460d8b5e99f9", "parsed_at": "2021-10-26T14:19:42.707Z" }, { "name": "GitHub Repo", "description": "A GitHub repository", "category": "Git Repository", "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { "id": "80711933", "web_url": "https://github.com/secureCodeBox/secureCodeBox", "full_name": "secureCodeBox/secureCodeBox", "owner_type": "Organization", "owner_id": "34573705", "owner_name": "secureCodeBox", "created_at": "2017-02-02T09:48:05Z", "lastactivityat": "2021-10-26T11:44:02Z", "visibility": "public", "lastcommitid": "b16b0ddfbad578a35fe54100b9192165ac2f5c0c" }, "id": "11b20733-eba5-47d7-b64d-09cf22bab29b", "parsed_at": "2021-10-26T14:19:42.707Z" }, // And so on... ] ``` So, now that we have a list of repositories, how do we scan them? are probably one of the most useful features of secureCodeBox. They allow you to use results from a previous scan to dynamically create targeted follow-up scans. You can even include a selector to filter which results you want to act on, and which you want to ignore. Consider the following cascading scan definition: ```yaml apiVersion: "cascading.securecodebox.io/v1" kind: CascadingRule metadata: name: "find-ua-parser-backdoor" labels: securecodebox.io/invasive: non-invasive securecodebox.io/intensive: medium spec: matches: anyOf: name: "GitHub Repo" attributes: visibility: public scanSpec: ``` This (incomplete) example of a cascading scan rule shows off some of their features: We can categorize how resource-intensive and invasive the defined scans are (so that the preceding scans can filter out specific cascading rules that are too invasive for the current engagement), and filter which results we want to act on. In this example, we want to act on result with the name "GitHub Repo" that have an attribute called "visibility" that is set to "public". Of course, we can drop the latter part if we also want to analyze private repositories. So, this is all well and good, but how can we turn this into a SAST scan? For this, we turn to the newest member in the family of secureCodeBox scanners: semgrep. is an open source SAST scanner that we . It has support for many popular programming languages and a , but also allows you to in a fairly intuitive and flexible syntax. For example, this is a basic rule to find `package-lock.json` files that contain a reference to an affected version of the UA-parser-js library: ```yaml rules: id: backdoored-ua-parser pattern-either: pattern: | "ua-parser-js": { "version": "0.7.29", ... } pattern: | "ua-parser-js": { "version": "0.8.0", ... } pattern: | "ua-parser-js": { "version": "1.0.0", ... } paths: include: package-lock.json message: Backdoored version of ua-parser-js found languages: [json] severity: ERROR metadata: references: https://www.bleepingcomputer.com/news/security/popular-npm-library-hijacked-to-install-password-stealers-miners/ ``` This rule will search through all `package-lock.json` files and look for any references to the affected versions of the library (of course, in practice you may want to refine this rule a bit more, but it is good enough for this example). So, we have a rule, and we have a list of repositories - but how do we get the code from the repositories to where the scanner is? By using another newly introduced feature of secureCodeBox: init containers. If you already have some experience with Kubernetes, you may already know the concept of . Briefly, they are containers that are run before the main container of a job is run, and are used to provision specific data or configurations files for the main container. With secureCodeBox 3.2, we have

We can use this to provision the Git repository into the semgrep scan container, specifying a so that they can share the downloaded data. We can thus complete the cascading rule we began writing above. ```yaml apiVersion: "cascading.securecodebox.io/v1" kind: CascadingRule metadata: name: "find-ua-parser-backdoor" labels: securecodebox.io/invasive: non-invasive securecodebox.io/intensive: medium spec: matches: anyOf: name: "GitHub Repo" attributes: visibility: public scanSpec: scanType: "semgrep" volumes: name: repo emptyDir: {} volumeMounts: name: repo mountPath: "/repo/" parameters: "-c" "s/DzLd" "--max-target-bytes 0" "/repo/" initContainers: name: "git-clone" image: bitnami/git command: git clone "https://$(GITHUBTOKEN)@github.com/{{{attributes.fullname}}}" /repo/ volumeMounts: mountPath: "/repo/" name: repo env: name: GITHUB_TOKEN valueFrom: secretKeyRef: name: github-access-token key: token ``` If you load this cascading rule and start the git-repo-scanner scan we defined above, it automatically starts scans for all repositories found by git-repo-scanner (make sure the and scantypes as well as the are installed). After waiting a while for the scan to finish, you can see the results using `kubectl get scans` - since we have a simple rule that only matches one specific vulnerability, any finding that is shown in the results should be investigated (find out which repository it belongs to by running `kubectl describe scan [name of the scan] | grep github.com`). However, maybe you want to also inspect the data in an application security management system like ? secureCodeBox has had a for a while. It allows you to automatically import data from your scans to DefectDojo, and optionally pull the results of the import back into secureCodeBox. You can control how the imported data is assigned to products, engagements and tests in DefectDojo by using scan annotations, which also support templating for cascading scans. For example, the following extended cascading scan definition now assigns each scan to a DefectDojo product for that repository, and also includes some version information. ```yaml apiVersion: "cascading.securecodebox.io/v1" kind: CascadingRule metadata: name: "find-ua-parser-backdoor" labels: securecodebox.io/invasive: non-invasive securecodebox.io/intensive: medium spec: scanAnnotations: defectdojo.securecodebox.io/product-type-name: "Git Repository" defectdojo.securecodebox.io/product-name: "{{{ attributes.full_name }}}" defectdojo.securecodebox.io/product-tags: git,github,repository,code defectdojo.securecodebox.io/engagement-name: "semgrep-ua-parser-js" defectdojo.securecodebox.io/engagement-version: "{{ attributes.lastcommitid }}" defectdojo.securecodebox.io/test-title: "{{{ attributes.fullname }}} - {{ attributes.lastcommit_id }}" ``` :::caution If you want to try this in practice, note that it will currently only work if the DefectDojo hook is configured not to write back its results to secureCodeBox (`--set="defectdojo.syncFindingsBack=false"` during installation of the hook). Otherwise, the DefectDojo hook will overwrite the findings of the git-repo-scanner job, causing the cascading jobs not to be run. Also note that at the time of writing, the current version of DefectDojo has a , which should be fixed in the next release (but should not affect this example). ::: Of course, we also want to help you follow security best practices in your security scanning infrastructure, so starting with secureCodeBox 3.3, you can also run the DefectDojo hook with an API key with limited permissions instead of the full administrative access that was previously required. For more details, see the . We hope this example shows how SAST scans can be a valuable addition to your secureCodeBox toolbelt, even if you are already using such scanners as part of the CI pipeline. Of course, nothing stops you from using to keep re-running these scans on a regular basis to check for additional issues like (which is also possible with ) or in your repositories, just to make sure the existing processes did not miss anything. As always, our goal is to provide a platform that works with your workflows instead of prescribing our own. We are looking forward to hearing your own stories and ideas for using secureCodeBox - (Channel `#project-securecodebox`) or to get in touch.