DevSecOps Tutorial: Software Composition Analysis (SCA) in CI/CD Pipeline

DevSecOps Tutorial: Software Composition Analysis (SCA) in CI/CD Pipeline

Introduction

I will brief the step by step how we can implement Software Composition Analysis (SCA) or also known as Open-Source Analysis Security Test (OAST) in your CI/CD pipeline. Before we can proceed with the nitty-gritty of of the CI/CD pipeline steps, below is the pre-requisite of this tutorial:

Requirements:

CI Tool: An account of SaaS GitLab/GitLab on-premises and GitLab Runner. Your GitLab Runner must be docker-executor enable, you may setup it via this link.

Project / Source Code: We will use free/open-source django project via https://github.com/secfigo/django.nv.git


In this tutorial we will implement SCA tool called Safety , it's a python SCA tool to scan an application for known vulnerable components and store the output result as artifact on our GitLab for future reference.

Step 0 : Setup a GitLab Account and GitLab Runner

If you don't have GitLab account yet, please refer this URL to setup it 1st, because below steps actually after you go setup your GitLab.

Step 1: GitLab Repo setup & Clone django-nv source code

Once we clone the repo(as shared above and create new project in our GitLab), we need to update yml file below;

gitlab

Step 2: Update your .gitlab-ci.yml file

stages:
  - build
  - test
  - release
  - preprod
  - integration
  - prod

build:
  stage: build
  script:
   - virtualenv env
   - source env/bin/activate
   - pip install -r requirements.txt
   - python manage.py check

sca-test:
  stage: test
  script:
    - docker pull hysnsec/safety
    - docker run -v $(pwd):/src --rm hysnsec/safety safety check -r requirements.txt --json > oast-results.json
  artifacts:
    paths: [oast-results.json]
    when: always
  allow_failure: true

integration:
  stage: integration
  script:
    - echo "This is an integration step"
    - exit 1
  allow_failure: true # Even if the job fails, continue to the next stages

prod:
  stage: prod
  script:
    - echo "This is a deploy step"
  when: manual # Continuous Delivery

Step 3: Commit YML file and Run the CI/CD Pipeline

Once, we done editing our .gitlab-ci.yml file, we need to click "commit" button below to auto-deploy or run our SCA test in CI/CD pipeline

commit-button

Step 4: Run CI/CD Pipeline and See SCA Result JSON file

We can see our CI/CD pipeline running in pipeline page;

CICD-Running

Once, done we will get overall stages status; as we can see below or SCA job is failed, since we allow failure in our YML file, it proceed to next stages;

overall-process

Step 5: See SCA Test Result file

To see our SCA test result, we can click on Test stage on sca-test job and see our Result JSON file and see all the Safety scanner result on dependency security test is stored in JSON file below under artifact section;

result-json

Step 6: See all the Vulnerability found by Safety Tool

In sca-result.json it will show something like below;

[
    [
        "django",
        "<1.11.27",
        "1.8.3",
        "Django before 1.11.27, 2.x before 2.2.9, and 3.x before 3.0.1 allows account takeover. A suitably crafted email address (that is equal to an existing user's email address after case transformation of Unicode characters) would allow an attacker to be sent a password reset token for the matched user account. (One mitigation in the new releases is to send password reset tokens only to the registered user email address.) See CVE-2019-19844.",
        "37771"
    ],
    [
        "django",
        "<1.8.10",
        "1.8.3",
        "The password hasher in contrib/auth/hashers.py in Django before 1.8.10 and 1.9.x before 1.9.3 allows remote attackers to enumerate users via a timing attack involving login requests.",
        "33074"
    ],
    [
        "django",
        "<1.8.10",
        "1.8.3",
        "The utils.http.is_safe_url function in Django before 1.8.10 and 1.9.x before 1.9.3 allows remote attackers to redirect users to arbitrary web sites and conduct phishing attacks or possibly conduct cross-site scripting (XSS) attacks via a URL containing basic authentication, as demonstrated by http://mysite.example.com\\@attacker.com.",
        "33073"
    ],
    [
        "django",
        "<1.8.15",
        "1.8.3",
        "The cookie parsing code in Django before 1.8.15 and 1.9.x before 1.9.10, when used on a site with Google Analytics, allows remote attackers to bypass an intended CSRF protection mechanism by setting arbitrary cookies.",
        "25718"
    ],
    [
        "django",
        ">=1.8,<1.8.16",
        "1.8.3",
        "Django before 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3, when settings.DEBUG is True, allow remote attackers to conduct DNS rebinding attacks by leveraging failure to validate the HTTP Host header against settings.ALLOWED_HOSTS.",
        "33075"
    ],
    [
        "django",
        ">=1.8,<1.8.16",
        "1.8.3",
        "Django 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3 use a hardcoded password for a temporary database user created when running tests with an Oracle database, which makes it easier for remote attackers to obtain access to the database server by leveraging failure to manually specify a password in the database settings TEST dictionary.",
        "33076"
    ],
    [
        "django",
        ">=1.8,<1.8.18",
        "1.8.3",
        "Django 1.8.18 fixes two security issues in 1.8.17.\r\n\r\nCVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs\r\n============================================================================================\r\n\r\nDjango relies on user input in some cases  (e.g.\r\n:func:`django.contrib.auth.views.login` and :doc:`i18n </topics/i18n/index>`)\r\nto redirect the user to an \"on success\" URL. The security check for these\r\nredirects (namely ``django.utils.http.is_safe_url()``) considered some numeric\r\nURLs (e.g. ``http:999999999``) \"safe\" when they shouldn't be.\r\n\r\nAlso, if a developer relies on ``is_safe_url()`` to provide safe redirect\r\ntargets and puts such a URL into a link, they could suffer from an XSS attack.\r\n\r\nCVE-2017-7234: Open redirect vulnerability in ``django.views.static.serve()``\r\n=============================================================================\r\n\r\nA maliciously crafted URL to a Django site using the\r\n:func:`~django.views.static.serve` view could redirect to any other domain. The\r\nview no longer does any redirects as they don't provide any known, useful\r\nfunctionality.\r\n\r\nNote, however, that this view has always carried a warning that it is not\r\nhardened for production use and should be used only as a development aid.",
        "33301"
    ],
    [
        "django",
        ">=1.8,<1.8.4",
        "1.8.3",
        "contrib.sessions.middleware.SessionMiddleware in Django 1.8.x before 1.8.4, 1.7.x before 1.7.10, 1.4.x before 1.4.22, and possibly other versions allows remote attackers to cause a denial of service (session store consumption or session record removal) via a large number of requests to contrib.auth.views.logout, which triggers the creation of an empty session record.",
        "25727"
    ],
    [
        "django",
        ">=1.8,<1.8.7",
        "1.8.3",
        "The get_format function in utils/formats.py in Django before 1.7.x before 1.7.11, 1.8.x before 1.8.7, and 1.9.x before 1.9rc2 might allow remote attackers to obtain sensitive application secrets via a settings key in place of a date/time format setting, as demonstrated by SECRET_KEY.",
        "25714"
    ],
    [
        "django",
        ">=1.8a1 ,<1.8.19",
        "1.8.3",
        "If ``django.utils.text.Truncator``'s ``chars()`` and ``words()`` methods were\r\npassed the ``html=True`` argument, they were extremely slow to evaluate certain\r\ninputs due to a catastrophic backtracking vulnerability in a regular\r\nexpression. The ``chars()`` and ``words()`` methods are used to implement the\r\n``truncatechars_html`` and ``truncatewords_html`` template filters, which were\r\nthus vulnerable.",
        "35796"
    ],
    [
        "django",
        ">=1.8a1 ,<1.8.19",
        "1.8.3",
        "The ``django.utils.html.urlize()`` function was extremely slow to evaluate\r\ncertain inputs due to a catastrophic backtracking vulnerability in a regular\r\nexpression. The ``urlize()`` function is used to implement the ``urlize`` and\r\n``urlizetrunc`` template filters, which were thus vulnerable.\r\n\r\nThe problematic regular expression is replaced with parsing logic that behaves\r\nsimilarly.",
        "35797"
    ]
]

Recap

We accomplished setup our 1st SCA or Open-Source Analysis Security Test (OAST) in CI/CD pipeline. So far we had done below;

  1. We had setup and clone django-nv source code in GitLab.
  2. We updated .gitlab-ci.yml file with Docker Safety CSA tool
  3. We successfully found the vulnerability in our code from SCA scanning.
  4. We have JSON file as our improve plan in our codes.

Next you should read

Tutorial: Use Retire.js to Scan Javascript Code.


Share Tweet Send
0 Comments
Loading...