Installing

Fluid Asserts is hosted on PyPI, so you can install it easily using pip3 on a system with Python 3:

$ pip3 install -U fluidasserts

For normal/interactive usage, you should set the environment variable FA_STRICT to false (see below). In an UNIX-like OS:

$ export FA_STRICT="false"

In Windows:

> set FA_STRICT="false"

Now you’re ready to begin testing vulnerabilities’ closure.

Inside a Docker container

If you have Docker you can check out and run Asserts inside a container. Just

$ docker pull fluidattacks/asserts

And then go inside the container:

$ docker run -it fluidattacks/asserts sh
/ # asserts
#     ________      _     __   ___                        __
#    / ____/ /_  __(_)___/ /  /   |  _____________  _____/ /______
#   / /_  / / / / / / __  /  / /| | / ___/ ___/ _ \/ ___/ __/ ___/
#  / __/ / / /_/ / / /_/ /  / ___ |(__  |__  )  __/ /  / /_(__  )
# /_/   /_/\__,_/_/\__,_/  /_/  |_/____/____/\___/_/   \__/____/
#
# v. 19.11.18612
#  ___
# | >>|> fluid
# |___|  attacks, we hack your software
#
---
summary:
  test time: 0.0010 seconds
  checks:
    total: 0 (100%)
    errors: 0 (0.00%)
    unknown: 0 (0.00%)
    closed: 0 (0.00%)
    opened: 0 (0.00%)
  risk:
    high: 0 (0%)
    medium: 0 (0%)
    low: 0 (0%)

Make sure to do the docker pull before every docker run to ensure you are running the latest Asserts version.

From inside the container you could run Asserts from the python interactive shell, or quickly whip up a script using vi. But it would be much more useful to mount the directory where your exploits live into the container:

$ docker run -v /home/me/myexploits/:/exploits/ -it fluidattacks/asserts sh
/ # asserts /exploits/open-sqli.py
#     ________      _     __   ___                        __
#    / ____/ /_  __(_)___/ /  /   |  _____________  _____/ /______
#   / /_  / / / / / / __  /  / /| | / ___/ ___/ _ \/ ___/ __/ ___/
#  / __/ / / /_/ / / /_/ /  / ___ |(__  |__  )  __/ /  / /_(__  )
# /_/   /_/\__,_/_/\__,_/  /_/  |_/____/____/\___/_/   \__/____/
#
# v. 19.11.18612
#  ___
# | >>|> fluid
# |___|  attacks, we hack your software
#
---
check: fluidasserts.proto.http -> has_sqli
description: Check SQLi vulnerability by checking common SQL strings in response.
status: OPEN
message: Bad text is present in response
vulnerabilities:
- where: http://testphp.vulnweb.com/AJAX/infoartist.php?id=3%27
  source: HTTP/Response/Body
  specific: HTTP/Implementation
  fingerprint:
    verb: GET
    status: 200
    headers:
      Server: nginx/1.4.1
      Date: Wed, 13 Nov 2019 22:12:36 GMT
      Content-Type: text/xml
      Transfer-Encoding: chunked
      Connection: keep-alive
      X-Powered-By: PHP/5.3.10-1~lucid+2uwsgi2
    sha256: 588702eb0b53294654f934d86664956e9739db47c34ffd8d703550cd5fd670a0
parameters:
  url: http://testphp.vulnweb.com/AJAX/infoartist.php?id=3%27
  args: []
  kwargs: {}
vulnerable_incidences: 1
when: 2019-11-13T22:13:22+0000
elapsed_seconds: 0.23
test_kind: DAST
risk: high
---
summary:
  test time: 0.3879 seconds
  checks:
    total: 1 (100%)
    errors: 0 (0.00%)
    unknown: 0 (0.00%)
    closed: 0 (0.00%)
    opened: 1 (100.00%)
  risk:
    high: 1 (100.00%)
    medium: 0 (0.00%)
    low: 0 (0.00%)

Inside your CI (Continuous Integration) pipeline

If you have an application subscribed to our Continuous Hacking Service which includes the use of Asserts, you can integrate it into your CI/CD pipeline to ensure that your software builds and ships with no open vulnerabilities. We will provide a custom Docker container with the specific tests you need and maintain the build-breaker exploit.

To achieve this, follow these steps:

  1. Add the required environment variables ID and SECRET. Don’t worry, the values will be provided by us!:

    • ID: an identifier that works like your username

    • SECRET: another identifier that works like your password

    For example, in GitLab, your environment would look like this:

    GitLab environment variables for using Asserts

    GitLab CI environment variables

  2. Add a job to run Fluid Asserts. For example:

    • in GitLab:

      Add these three lines to your .gitlab-ci.yml:

      fluidasserts:
        script:
          - docker pull fluidattacks/break-build
          - bash <(docker run fluidattacks/break-build --static --id ${ID} --secret ${SECRET})
      
    • in Azure DevOps (VSTS),

      Add a Command Line task with the following script:

      docker pull fluidattacks/break-build
      bash <(docker run fluidattacks/break-build --static --id ${ID} --secret ${SECRET})
      
  3. Now your pipeline will break if any vulnerability is found to be open. In order to not break the build, but still run the tests, add the --no-strict flag on the command.

  4. You can customize the execution

    --static

    Run the static container.

    --dynamic

    Run the dynamic container.

    --cpus N

    Add this flag to allow execution in N host CPUs (defaults to 1)

    --id ID

    Use this flag to set your user ID

    --secret SECRET

    Use this flag to set your user Secret

    --no-strict

    Don’t Break the Build if any vulnerability is found to be open :(

CI stages

OK, I’m in. But in what stage should I test my app with Asserts?

Let’s think for a moment in the following architecture

Locally:

  1. Develop an amazing feature

  2. Push your code to the repository

Inside the continuous integration:

  1. Test the code

  2. Build the code

  3. Deploy an ephemeral environment

  4. Make a Pull/Merge Request

  5. Deploy the production environment

There are at least four good moments to perform closure testing.

  • just after pushing your code to the repository

  • after deploying to a staging or ephemeral environment

  • after deploying to the production environment

  • even after every single commit!

Post-production

Just as before, we log in to the artifacts repository, pull the custom image and run it with Docker. This job is run only in the master branch and in one of the latest stages, namely asserts-prod.

asserts-production:
  stage: asserts-prod
  script:
    - docker pull fluidattacks/break-build
    - bash <(docker run fluidattacks/break-build --dynamic --id ${ID} --secret ${SECRET})
  retry: 2
  only:
    - master

Post-ephemeral

But wait! We could catch bugs before deploying to production. If you use ephemeral environments, you can also perform closure testing in those:

Asserts-Review:
  stage: asserts-post-ephemeral
  script:
    - docker pull fluidattacks/break-build
    - bash <(docker run fluidattacks/break-build --dynamic --id ${ID} --secret ${SECRET})
  retry: 2
  except:
    - master
    - triggers

In contrast to the post-deploy job above, this one runs on the development branches, during the asserts-post-ephemeral stage. Otherwise, everything else is the same, just like staging environments mirror production environments.

Just after pushing your code

We can start catching bugs even only with the source code:

Asserts-Review:
  stage: asserts-code-test
  script:
    - docker pull fluidattacks/break-build
    - bash <(docker run fluidattacks/break-build --static --id ${ID} --secret ${SECRET})
  except:
    - master
    - triggers

In contrast to the post-ephemeral job above, this one runs on the development branches, during the asserts-code-test stage, over the source code only.

Pre-commit

As a developer you might be thinking “why wait until all other CI stages are finished if I just want to test whether my last commit fixed the security hole?” You could just run Asserts in your development machine, but sometimes tiny details (like dependencies versions) might cause the testing to pass in your machine but fail continuous integration.

In that case you might run the Dockerized incarnation of Asserts as a pre-commit hook:

- id: asserts-docker
  name: Running Asserts on the code
  description: Run Asserts to perform SAST
  entry: -v /path/to/your/code/:/code fluidattacks/asserts:latest /code/asserts.sh
  language: docker_image

This particular configuration is for the pre-commit tool, but can be adapted for similar tools like overcommit. The use of such tools is convenient for the developer, as tests can be quickly run in their machine with every commit:

Pre-commit pass

Pre-commit test passed

Pre-commit fail

Pre-commit test fails. Commiting is not allowed!

The same tests can also be run in CI time (for example, in a lint stage) to ensure that nothing is broken, even if the developer forgot to run it. Just

- pre-commit run --all-files

somewhere in your CI script.