YASE - Yet Another Software Engineer
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:
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/
bandit
: the command to run the tool.-r
(or --recursive
): tells Bandit to search for Python files recursively in the specified directory and its subdirectories.app/
: the path to your project’s main directory.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:
tests
, venv
, or asset folders.# 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:
pre-commit
framework.
Add this to your .pre-commit-config.yaml
: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
-f json
: saves in JSON format.-o bandit-report.json
: specifies the output filename.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.