14 Nov 2024 · Software Engineering

    Securing Your CI/CD Pipeline with Snyk Open Source and Semaphore

    8 min read
    Contents

    Security is a critical concern in modern software development, especially when dealing with open-source dependencies. Vulnerabilities in these libraries can introduce severe risks to your application, exposing it to potential attacks. That’s why it is essential to ensure that your codebase remains secure.

    Snyk, a powerful open-source security tool, helps you to identify and fix vulnerabilities in your codebase. When you combine it with Semaphore CI’s CI/CD pipeline, you can automate these checks and ensure that your software stays secure at every step of the development process.

    In this article, you will learn:

    • How Snyk works, with a focus on Snyk Open Source.
    • How to integrate Snyk with Semaphore CI for automated vulnerability scanning.
    • Best practices for securing your CI/CD pipeline.

    Let’s get started!

    Snyk Overview

    What is Snyk?

    Snyk is a comprehensive platform designed to secure every aspect of your application stack, from code to infrastructure. It provides a suite of tools to identify and remediate vulnerabilities in your codebase, including:

    One of Snyk’s standout features is its deep integration with CI/CD pipelines. It allows you to automatically run security scans.

    Snyk offers a free tier, making it easy for individual developers and small teams to get started.

    In this article, we’ll focus on Snyk Open Source. It automatically identifies and fixes vulnerabilities in open-source libraries and dependencies. It scans your project’s libraries, flags security risks, and offers advice to remediate the vulnerabilities.

    Snyk Open Source scans your project’s dependencies for vulnerabilities using its continuously updated vulnerability database. This database pulls from various sources, including the National Vulnerability Database (NVD), security advisories, GitHub issues, and Snyk’s in-house security research team.

    How to Use Snyk?

    You can utilize Snyk in several ways:

    • Web UI: Manage, configure, and fix issues through Snyk’s web interface.
    • CLI: Integrate Snyk into your local machine or CI/CD pipelines (which you will see in this article).
    • IDEs: Use Snyk within your development environment.
    • API: Programmatically integrate Snyk into your workflows (available only for Enterprise plans).

    Setting Up Snyk

    Follow these steps to get started with Snyk.

    1. Create a free Snyk Account by visiting the Snyk website.
    2. To run security checks locally, install the Snyk CLI:
    curl --compressed https://downloads.snyk.io/cli/stable/snyk-linux -o snyk
    chmod +x ./snyk
    sudo mv ./snyk /usr/local/bin/

    Check the installation guide for more installation options.

    1. After installation, authenticate Snyk CLI with your account by running:
    snyk auth

    This command will open a web browser where you can log in to your Snyk account. Finally, you should see the following messages in your Terminal:

    Opening in existing browser session.
    Your account has been authenticated.
    1. Navigate to your project’s directory and run the following command to scan for vulnerabilities:
    snyk test

    Snyk will analyze your project and provide a report of any existing vulnerabilities. For example:

    Tested 5 dependencies for known issues, found 5 issues, 5 vulnerable paths.
    
    
    Issues to fix by upgrading:
    
      Upgrade ch.qos.logback:logback-classic@1.2.3 to ch.qos.logback:logback-classic@1.2.13 to fix
      ✗ Insufficient Hostname Verification [Medium Severity][https://security.snyk.io/vuln/SNYK-JAVA-CHQOSLOGBACK-1726923] in ch.qos.logback:logback-core@1.2.3
        introduced by ch.qos.logback:logback-classic@1.2.3 > ch.qos.logback:logback-core@1.2.3
      ✗ Denial of Service (DoS) [High Severity][https://security.snyk.io/vuln/SNYK-JAVA-CHQOSLOGBACK-6094943] in ch.qos.logback:logback-core@1.2.3
        introduced by ch.qos.logback:logback-classic@1.2.3 > ch.qos.logback:logback-core@1.2.3
      ✗ Uncontrolled Resource Consumption ('Resource Exhaustion') [High Severity][https://security.snyk.io/vuln/SNYK-JAVA-CHQOSLOGBACK-6097493] in ch.qos.logback:logback-core@1.2.3
        introduced by ch.qos.logback:logback-classic@1.2.3 > ch.qos.logback:logback-core@1.2.3
      ✗ Denial of Service (DoS) [High Severity][https://security.snyk.io/vuln/SNYK-JAVA-CHQOSLOGBACK-6094942] in ch.qos.logback:logback-classic@1.2.3
        introduced by ch.qos.logback:logback-classic@1.2.3
      ✗ Uncontrolled Resource Consumption ('Resource Exhaustion') [High Severity][https://security.snyk.io/vuln/SNYK-JAVA-CHQOSLOGBACK-6097492] in ch.qos.logback:logback-classic@1.2.3
        introduced by ch.qos.logback:logback-classic@1.2.3

    Optionally, you can link your repository (like GitHub or Bitbucket) to allow Snyk to scan your project for vulnerabilities. However, we will skip this step as our focus will be on using Snyk within the CI/CD pipeline process.

    Integrating Snyk with Semaphore CI

    Now that you know how Snyk works, let’s integrate it into the Semaphore CI pipeline.

    1. First, you need a free Semaphore account. Visit the Semaphore website and choose either GitHub or Bitbucket for registration. In this tutorial, I will use GitHub.
    1. Add a new project by clicking the “+Create New” button.

    I’ve created a simple Maven project with minimal source code and a single JUnit test. I will connect my repository with Semaphore:

    1. Click on “Continue to workflow setup”. Semaphore will automatically initialize the project. You can add more people to it if you wish.
    2. Next, we need to create the workflow for the pipeline. You can configure the Semaphore pipeline via the UI or manually create the semaphore.yml file in your project. I will show you the first approach.
    3. Select the “Maven” template from the list. Click on “Customize” to override the default configuration:
    • Change the default machine type to e1-standard-2. The e1 series machines are appropriate for less compute and memory-intensive jobs.
    • Edit the Build block to combine the build and test steps into a single block since they share the same initial commands. Instead of duplicating these commands for each job, we can use the Prologue section to streamline the process. Add the shared commands to the Prologue, ensuring they run once before the jobs.

    The prologue commands:

    checkout
    sem-version java 17

    This command checks out the project’s code. The sem-version utility on Linux-based virtual machines allows you to set or switch the version of a programming language.

    The build job command:

    mvn -B package --file pom.xml

    This command compiles the project’s source code and packages it using Maven, creating a distributable artifact.

    The test job command:

    mvn test

    This command executes the project’s unit tests using Maven.

    • Click “+ Add Block” to add a job for the security scan:

    Security scan commands:

    checkout
    curl --compressed https://downloads.snyk.io/cli/stable/snyk-linux -o snyk
    chmod +x ./snyk
    sudo mv ./snyk /usr/local/bin/
    SNYK_TOKEN=$SNYK_TOKEN snyk test

    These commands install the Snyk CLI tool, make it executable, place it in a system directory, and initiate a vulnerability test using an authentication token. We reference the $SNYK_TOKEN variable, which serves for authentication with Snyk. As a best practice, this token is stored as a secret to avoid exposing sensitive information. To create the secret, expand the “Secrets” section and open “Manage Secrets” in a new tab.

    Select “Set up global secret” and name it “SNYK_TOKEN“. Input the token value, which you can retrieve from your Snyk account’s General Settings.

    Click on “Save Secret”.

    1. Go back to the workflow. The new secret name should appear under the Secrets section. Select it:
    1. Click the “Run the workflow” button, and Semaphore will automatically start the pipeline. Additionally, it will create a new branch called “setup-semaphore” in your GitHub repository.

    If you prefer the YAML creation approach, check out the link to my GitHub repository, which contains the content of the semaphore.yml file. Keep in mind that you still have to create the secret manually.

    Testing the Workflow

    The pipeline should pass because we don’t have any vulnerabilities yet:

    Let’s add an open-source library with known vulnerabilities to test the Security Scan job. Add this dependency to the pom.xml:

    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.2</version> <!-- Known vulnerability in this version -->
    </dependency>

    The pipeline should fail this time:

    Best Practices for Secure CI/CD Pipelines

    To maintain a secure CI/CD pipeline, consider these best practices for integrating security into your development workflow:

    • Run security scans on every pull request: Automate security scans to ensure every change is evaluated for vulnerabilities before merging.
    • Enforce policies against vulnerable code: Implement policies that prevent vulnerable code from being deployed.
    • Regularly update dependencies: Keep your dependencies up to date to minimize exposure to known vulnerabilities.
    • Store secrets as environment variables: Use environment variables or secret management tools to securely store sensitive information, like API tokens, and avoid hardcoding them in your pipeline configuration.
    • Break the build for critical issues: Set up your pipeline to fail if high-priority vulnerabilities are found, ensuring they are addressed before deployment.

    Conclusion

    Incorporating Snyk into your Semaphore CI pipeline is a powerful step towards enhancing the security of your applications.

    Throughout this article, you learned:

    • How Snyk, particularly Snyk Open Source, operates and what its key features are.
    • The step-by-step process for integrating Snyk with Semaphore CI for automated vulnerability scanning.
    • Best practices for securing your CI/CD pipeline, such as running security scans on every pull request and enforcing deployment policies against vulnerable code.

    Thank you for reading!

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    mm
    Writen by:
    I am a seasoned Java Developer with a passion for writing. I love exploring various tools and frameworks to expand my expertise beyond daily work. Crafting easy-to-follow tutorials is my way of helping professionals grow in their careers.
    Avatar for Kristina Nikolova
    Reviewed by:
    I picked up most of my soft/hardware troubleshooting skills in the US Army. A decade of Java development drove me to operations, scaling infrastructure to cope with the thundering herd. Engineering coach and CTO of Teleclinic.