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.

Installing with Nix

We are at the Official Nixpkgs collection.

  1. Install Nix as explained here.

    On most systems it’s enough to run:

    $ curl https://nixos.org/nix/install | sh
    
  2. Install fluidasserts:

    $ nix-env -i fluidasserts -f https://github.com/NixOS/nixpkgs/archive/master.tar.gz
    
  3. (Optional) Update fluidasserts:

    $ nix-env -u fluidasserts -f https://github.com/NixOS/nixpkgs/archive/master.tar.gz
    
  4. Get into a shell with fluidasserts!

    $ nix-shell -p fluidasserts
    

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. 20.10.38625
#  ___
# | >>|> fluid
# |___|  attacks, we hack your software
#
---
summary:
  test time: 0.0021 seconds
  checks:
    total: 0 (100%)
    errors: 0 (0.00%)
    unknown: 0 (0.00%)
    closed: 0 (0.00%)
    opened: 0 (0.00%)
  vulnerabilities: 0
  risk:
    high: 0 (0%)
    medium: 0 (0%)
    low: 0 (0%)
  exploits:
    total: 1

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. 20.10.38625
#  ___
# | >>|> 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, 14 Jan 1970 13:55:34 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: 2020-10-27T19:45:26+0000
elapsed_seconds: 0.22
test_kind: DAST
risk: high
---
summary:
  test time: 0.5955 seconds
  checks:
    total: 1 (100%)
    errors: 0 (0.00%)
    unknown: 0 (0.00%)
    closed: 0 (0.00%)
    opened: 1 (100.00%)
  vulnerabilities: 1
  risk:
    high: 1 (100.00%)
    medium: 0 (0.00%)
    low: 0 (0.00%)
  exploits:
    total: 1

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.