Elevating Container Security with Static Application Security Testing (SAST)


Why Scan? (A preamble for the middle manager)

Code security scanning involves analyzing source code for potential vulnerabilities and weaknesses that could be exploited by attackers. This process helps identify and remediate security flaws before they can be used to launch attacks, compromising sensitive data and disrupting business operations.

Container security scanning, on the other hand, focuses on detecting and mitigating vulnerabilities within container images, the lightweight and portable units of software that form the basis of cloud-native applications.

Implementing code security and container security scanning into other infrastructure offers several compelling benefits. By automating the process of identifying and addressing vulnerabilities, organizations can significantly reduce their attack surface and enhance their overall security posture. This proactive approach helps prevent data breaches, protect critical assets, and maintain compliance with industry regulations.

Gitlab offers a comprehensive set of container and security scanning tools, provided free to Gitlab users on every tier, and with Gitlab's Ultimate tier, a set of code vulnerability and security reporting dashboards is also included.

    Official documentation: Static Application Security Testing (SAST)

The scope of this post is to give an example of using the included security scanning tools provided by GitLab first by posting a small Python application with minor code vulnerabilities and then introducing a node.js vulnerability to trigger the Security and Vulnerability dashboards.



] Introduce a web app with weak code security posture

Introduced to the project is Python code that uses Flask to host a rest application that returns the Python version and the container OS version from a REST GET request type.

app = Flask(__name__)

@app.route('/')
def index():
    python_version = platform.python_version()
    linux_version = subprocess.check_output("cat /etc/os-release", shell=True).decode()
    return f"Python Version: {python_version}\nLinux Version:\n{linux_version}"

if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)


] Enabling the Static Application Security Testing (SAST) pipeline template

This commit step enables the built in Gitlab Static Application Security Testing (SAST) template which will run in the gitlab runner pipeline test job.

Involved is including the SAST template, to which the adding the pipeline job, test queues an job in the gitlab runner pipeline execution process.

Items to note:

  • Pipeline job naming

    Enabled and matching pipeline jobs for SAST and GitLab security template(s), require the job step in the GitLab pipeline to be named test: as subsequent templates are defined as children jobs of the test definition.

  • Defining the Include stanza

    Typically, these job templates are prepended and commented out in the first commit to .gitlab-ci.yml and are included by adding a stanza key called "include".

    Each template is listed as a string.

stages:
- npm_install
- build
- test

include:
  - template: SAST.gitlab-ci.yml

sast:
  stage: test
  script:
    - /analyzer run
  artifacts:
    reports:
      sast: gl-sast-report.json


] Run the SAST test job pipeline step against application code

Running the test pipeline job for SAST is an automatic step which is queued and completed by the gitlab runner.

Output for the pipeline is grouped into the unique pipeline job id.

Pipeline Job for SAST test



] Using automatically generated report artifacts

Artifacts (objects) are associated to finished pipeline jobs regardless of the outcome state. The two jobs triggered from the SAST pipeline execution step are listed here.

  • nodejs-scan-sast
  • semgrep-sast

This repository has an associated Artifact repository, which GitLab enabled by default for this project.

Job Artifacts for SAST test

Artifact naming:

Below is an example artifact name declaration for the sast job step in test.

The gl-sast-report.json artifact is defined to help illustrate naming reports in the artifacts stanza.

This is a default setting that is not neccesary to declare in gitlab-ci.yml as it is defined in the included SAST pipeline template.

sast:

...

  artifacts:
    reports:
      sast: gl-sast-report.json

Further report artifact names are listed below to help complete this explanation.

  sast: gl-sast-report.json
  container_scanning: gl-container-scanning-report.json
  dependency_scanning: gl-dependency-scanning-report.json
  cyclonedx: "**/gl-sbom-*.cdx.json"

Note: In all Gitlab user tiers, the report artifacts are generated, and can be downloaded as JSON objects. Artifacts can be fed to a third-party SEIM without using the Gitlab Vulnerability and Security Dashboards.



] Dashboard: Project Security

Gitlab Ultimate tier offers dashboard reporting, which interprets the results the SAST job automatically generated Artifacts.

In this example, the Project Security Dashboard shows that 1 code vulnerability has been flagged as Critical and 3 additional vulnerabilities have been flagged as Medium.

Security dash for SAST test

This dashboard is configurable to display vulnerabilities over time with a severity classification.



] Dashboard: Project Vulnerability

Let's drill into the details and find out what this Dashboard tries to tell us.

Drilling into the Vulnerability dashboard, we can see interpreted detail from the gl-sast-report.json

vulnerability dash for SAST test

Warnings have been issued for lines 3, 10 and 14 of the app.py server code.

03  import subprocess

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Description: Consider possible security implications associated with subprocess module.

Severity: Medium

10  linux_version = subprocess.check_output("cat /etc/os-release", shell=True).decode()

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Description: Found subprocess function check_output with shell=True. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use shell=False instead.

Severity: Critical

14  app.run(host='0.0.0.0', debug=True)

Active debug code

Description The Flask application is running with debug=True configured. By enabling this option, certain exceptions or errors could cause sensitive information to be leaked in HTTP responses. Additionally, it is not recommended to run a Flask application using Flask.run(...) in production. Instead, a WSGI server such as gunicorn or waitress be used instead. For more information on deployment options for Flask applications see:

https://flask.palletsprojects.com/en/2.3.x/deploying/

Severity: Medium

] Section summary

As an overview for SAST code inspection, GitLab's Vulnerability dashboard reports the offending line and offers a comprehensive solution to resolve the identified issue.

To end this overview, the vulnerability issues are resolved in the following commit:



] Using the Vulnerability dashboard to confirm and resolve issues

With the critical python issue resolved and committed, a pipeline job has been run and shows the new scan results in the Vulnerability Dashboard.

The Vulnerability Dashboard shows a resolved status and asks for the project operator to "do something" with the posted alert.

vulnerability dash for SAST test

Next, by marking the Medium severity vulnerabilities as Confirmed the Dashboard captures the confirmation state for further management.

vulnerability dash for SAST test



] Introducing a Node vulnerability to the project

In a commit to add template scanning, a node dependency has been introduced to the project with known security issues.

"lodash": "4.17.10"

Further info on lodash: Known vulnerabilities in the lodash package



] Extend GitLab Security Scanning Capabilities with Templates

Extending the GitLab platform's ability to scan, two templates are added to .gitlab-ci.yml deepening the depth of a code security defensive strategy.

Enabled are the following Gitlab security, container and dependancy scanning templates.

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml

The $CS_IMAGE variable has also been set point to the container intended for scanning.

variables:
  CS_IMAGE: "registry.gitlab.com/cipherpop-guidance/containerscanning:main"

Further documentation on setting container scanning variables is hosted at GitLab:



] Validating SAST and newly added test pipeline jobs

Follwing a code commit, the pipeline to scan for vulnerabilities has triggered and a new series of report artifacts have been generated in concert with the newly added templates to scan the defined container and project dependancies.

vulnerability dash for SAST test

Completed jobs in the test pipeline job:



] Referencing Vulnerability Dashboard changes

Following the added code vulnerability, the Vulnerability Dashboard is displaying a staggering set of 5 Critical, 59 High, 224 Medium and 503 Low vulnerability issues from the latest pipeline test scanning job.

vulnerability dash for SAST test



] Summary

GitLab SAST, Container Security, and Dependency scanning are potent tools available to all tiers.

Additionally, early detection of security flaws can save organizations time and resources that would otherwise be spent on incident response and remediation.

The implementation of code security and container security scanning into code infrastructure is a crucial step towards achieving a comprehensive and effective security strategy. By proactively identifying and addressing vulnerabilities, Code owners and SREs can safeguard data, protect systems, and maintain business continuity.

More info on security can be found at cipherpop.com

links

social