Security Tests

YASE - Yet Another Software Engineer

Security Tests

Let’s now move on to security tests, another important part of testing, especially for applications that need to be exposed externally to the internet.

There are some easy-to-use tools that, with a little configuration, allow testing for the main security issues of a web application, achieving a good level of security with minimal effort. These tools are also open source; specifically, we’re talking about:

Bandit

The first is a security linter also developed by PyCQA, like Pylint.

In short, it’s a static analysis security testing (SAST) tool designed specifically to find common security issues in Python code. It doesn’t execute the code but analyzes it for patterns known to be potentially insecure.

First, it needs to be installed:

pip install bandit

The most common use of Bandit is to run it recursively on your project’s main directory. Bandit will analyze all .py files it finds.

If your FastAPI project is in a directory called app:

bandit -r app/

You can customize Bandit’s behavior through a configuration file (usually bandit.yaml or .bandit in the project root) or via command-line options.

Common Use Cases for Configuration:

# content of the bandit.yaml file
exclude_dirs: ["venv", "tests", ".*/migrations/"]
skips: ['B101', 'B311'] # skip these tests
# Defines minimum levels for reports (inclusive)
level: "MEDIUM" # Options: ALL, LOW, MEDIUM, HIGH
confidence: "MEDIUM" # Options: ALL, LOW, MEDIUM, HIGH

To get the maximum benefit, integrate Bandit into your workflow:

repos:
-   repo: https://github.com/PyCQA/bandit
    rev: 1.7.9 # Use the latest stable version
    hooks:
    -   id: bandit
        args: ["-c", "bandit.yaml"] # Optional: specify a config file

If you want to save the scan result to a file, perhaps in JSON format, to process it later via a log aggregator and extract additional information (Grafana), you can use the “-f” and “-o” parameters like this:

bandit -r app/ -f json -o bandit-report.json

Wapiti3

Wapiti it’s a DAST (Dynamic Application Security Testing) tool. This means it interacts with your application while it’s running, sending HTTP/HTTPS requests and analyzing responses to find vulnerabilities. It simulates attacks that a malicious actor might attempt.

Wapiti can search for common vulnerabilities such as:

First, let’s install Wapiti3:

pip install wapiti3

To test the application with Wapiti, you need to start it first. So, you need to run the server locally (please, never test the production app with Wapiti3 except in special, very carefully considered cases):

fastapi run app.main.py # Or however you run your FastAPI app, e.g., uvicorn app.main:app

I refer you to the official Wapiti3 guide to see all the possible commands, which are numerous. But, just to give you an idea, the command below can be considered the main, most generic one, suitable for a variety of situations (assuming the application is exposed on https://www.google.com/url?sa=E\&source=gmail\&q=http://127.0.0.1:8000/):

wapiti -u http://127.0.0.1:8000/ \
-x http://127.0.0.1:8000/logout \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>" \
-f json \
-o report_wapiti.json # Renamed output file for clarity

As you can easily guess, the entire application will be tested, meaning all routes that Wapiti3 can find autonomously, except for “/logout” to prevent the user from being disconnected.

A valid bearer token is passed (in this case, <YOUR_JWT_TOKEN> should be replaced with an actual token). Everything is saved in report_wapiti.json, in JSON format, for future processing or for insertion into a dashboard (Grafana). Alternatively, for readability, the report can also be saved in HTML format, which is very convenient and easy to read.