DevSecOps part 3: Scanning Live Web Applications with Nuclei

This article is part of a series about integrating security tooling in the development process. You can find the rest of the articles here:

Note: This tutorial is based on the repository resulting from part 2. If you haven't achieved it yet, no worries! You can directly fetch the result from github. If you already have done the two first parts of the tutorial, you can switch to the next section.

First, fork https://github.com/glimow/dvpwa

Then, clone your newly forked repository and switch to the right branch:

git clone -b tutorial-part-2 git@github.com:<your-username>/dvpwa.git

Security Integration Testing, Automated. 💫

In the last tutorial, we detected insecure code patterns in our application thanks to semgrep. Nice! But code analysis can't find all security flaws: some are related to the environment, to configuration.

Some are simply too complex to be found by automated tools reading the code.

To have an additional layer of security testing that is closer to the application's production context, security teams use specialized tools that will simulate attacks against the running application and report the successful ones.

This process is called Dynamic Application Security Testing (DAST).

Just as code security analysis ones, DAST tools have been hard to use, or expensive, or both. Or worth, coded fully in Java. But recently, a new free & open source project got my attention: nuclei.

Nuclei is an easy-to-use application security testing tool written in go. It leverages the community to create new automated tests using simple YAML template files.

Nuclei scans your web application based on thousands of community-written YAML templates

In a simple command line, nuclei can run almost 2500 security tests against your applications at golang speed. Which is fast. 🚀

You know where this is going, right? Let's try it against our Damm Vulnerable Python Web App!

Running Nuclei on a Web App ☠️

First, let's install Nuclei.

For macOS users, it's pretty straightforward:

brew install nuclei

For Linux users, unfortunately, nuclei do not provide any package manager installation, so you will have either to use go or download the binary. For the sake of brevity, we will use the binary in this tutorial.

wget https://github.com/projectdiscovery/nuclei/releases/download/v2.5.3/nuclei_2.5.3_linux_amd64.zip
unzip nuclei
sudo mv ./nuclei /usr/bin
nuclei

Which should get you something like:

Of course, there are no results, as we didn't give any URL!

Let's startup dvpwa so we can test it for real. Open another terminal, go into the dvpwa repository you used for this tutorial, and run:

docker-compose up

Thanks to god's will (and docker being up to date), you should see the following:

Your vulnerable python web app is up and running on port 8080. Let's scan it hard.

In your first console, run:

nuclei -u http://localhost:8080

Which should give you a result like:

In just 5 minutes, we detected that our python application was missing a lot of security features. If the machine you used has some open ports, nuclei might even detect them and give you a few more security alerts!

Integrating Nuclei inside the CI/CD

Fortunately, nuclei developers already created a GitHub Action for easy integration into any CI/CD pipeline.

"But wait, if we are testing the live application, that means we will have to launch the full application inside GitHub Actions?"

Yes. Exactly. But no worries, it is super easy: docker-compose works out of the box!

Just add the following to your .github/workflows/main.yaml :

  dynamic_security_testing:
    runs-on: ubuntu-latest
    name: Scan live web app for security flaws
    steps:
      - uses: actions/checkout@v2

      - name: Start containers
        run: docker-compose -f "docker-compose.yml" up -d --build

      - name: Dynamic Security Testing
        uses: projectdiscovery/nuclei-action@main
        with:
          target: http://localhost:8080

      - name: Stop containers
        if: always()
        run: docker-compose -f "docker-compose.yml" down

Then, in the console:

git add .github/workflows
git commit -m "Add dynamic security testing"
git push origin master

And you should see your new job appearing in your repository's Actions panel.

Note that our dynamic scan did not fail, because nuclei found only vulnerabilities with a less-than-low criticality.

Conclusion 😎

Again, in only a few steps, we installed a tool that scans our app for vulnerabilities directly inside the CI/CD. This time, we scanned our live, running app using HTTP requests sent by nuclei, a community-driven web app security scanner.

In the next tutorial, we will have a look at how to detect insecure packages inside of docker images  🚀

Follow Escape on Twitter, or check our website

for more human-readable appsec content!

Tristan Kalos

Tristan Kalos

Co-founder & CEO of Escape, in charge of product, sales and marketing. I was a dev before.