Forticheck
FortiCheck is a powerful, offline static analysis tool designed to uncover security risks, misconfigurations, and attack paths in FortiGate firewall configurations. Unlike simple compliance checkers, FortiCheck builds a graph-based model of your network to understand the intent and impact of your policies.
Install / Use
/learn @cumakurt/ForticheckREADME
FortiCheck
Security Analysis for FortiGate Firewalls
FortiCheck is a powerful, offline static analysis tool designed to uncover security risks, misconfigurations, and attack paths in FortiGate firewall configurations. Unlike simple compliance checkers, FortiCheck builds a graph-based model of your network to understand the intent and impact of your policies.
Key Features
- Deep Policy Analysis: Detects shadow rules, redundancy, and ordering anomalies.
- Attack Path Simulation: Simulates multi-hop attack vectors (e.g., Internet → DMZ → Internal) using graph theory.
- Exposure Analysis: Identifies internal assets exposed to the Internet or other untrusted zones.
- User & VPN Auditing: accurate checks for MFA violations, weak VPN encryption (DES/3DES/MD5), and legacy IKEv1 usage.
- Security Profile Gaps: Finds policies missing critical security profiles (IPS, AV, Web Filter).
- Context-Aware Risk Scoring: Assigns a risk score (0-100) to every finding based on exposure, asset sensitivity, and trust levels.
- Professional Reporting: Generates a self-contained, interactive HTML dashboard suitable for C-level executives and technical teams.
Installation
Prerequisites: Python 3.11+
Using requirements.txt
git clone https://github.com/cumakurt/forticheck.git
cd forticheck
pip install -r requirements.txt
pip install -e .
pip install -r requirements.txtinstalls the runtime dependencies (click, pydantic, netaddr, networkx, jinja2, rich, pyyaml).pip install -e .installs FortiCheck in editable mode and registers theforticheckcommand. Usepip install .for a normal (non-editable) install.
Using Poetry
git clone https://github.com/cumakurt/forticheck.git
cd forticheck
poetry install
Install from GitHub
pip install git+https://github.com/cumakurt/forticheck.git
For development (tests, linting), use Poetry or install with dev extras: pip install -e ".[dev]".
Docker
FortiCheck can be run in a container without installing Python or dependencies on the host. You only need Docker installed.
Build the image
From the project root:
git clone https://github.com/cumakurt/forticheck.git
cd forticheck
make docker-build
# or: docker build -t forticheck:latest .
Quick start
Place your FortiGate config in the current directory, mount it as /workspace, and run:
# Config and report in current directory (recommended)
docker run --rm -v "$(pwd):/workspace" forticheck:latest analyze -c sample_fortigate.conf -o /workspace/report.html
# Report: ./report.html
Where reports are written
The container uses /workspace as the working directory. You must mount your current directory so the config file is visible and the report is written to your host:
| Goal | Mount | Config | Output |
|------|--------|--------|--------|
| Current directory | -v $(pwd):/workspace | -c sample.conf or -c /workspace/sample.conf | -o /workspace/report.html |
| /tmp on host | -v /tmp:/tmp | Config must be in /tmp | -o /tmp/report.html |
Note: On some systems, writing to
/tmpmay cause permission errors. Prefer/workspace(current directory) for output.
Example: Using Make
make docker-build
make docker-run CONFIG=sample_fortigate.conf
# Report: ./forticheck_report.html (default)
make docker-run CONFIG=sample_fortigate.conf OUTPUT=audit.html
# Report: ./audit.html
Example: Report in current directory
docker run --rm -v "$(pwd):/workspace" forticheck:latest analyze -c /workspace/fortigate.conf -o /workspace/audit_report.html
# Report: ./audit_report.html
Example: Report in /tmp
cp /path/to/fortigate.conf /tmp/
docker run --rm -v /tmp:/tmp forticheck:latest analyze -c /tmp/fortigate.conf -o /tmp/forticheck_report.html
# Report on host: /tmp/forticheck_report.html
Example: HTML and JSON, custom trust, custom rules
Mount a directory that contains your config, optional trust_levels.yaml, and optional custom_rules.yaml. Output is written to the same directory.
docker run --rm -v "$(pwd):/workspace" forticheck:latest analyze \
-c /workspace/fortigate.conf \
-o /workspace/audit \
-f both \
--zones-trust /workspace/trust_levels.yaml \
--rules /workspace/custom_rules.yaml
# Creates: ./audit.html and ./audit.json
Example: Config diff with Docker
Mount a directory containing both configs; output the diff JSON to the same directory.
docker run --rm -v "$(pwd):/workspace" forticheck:latest diff \
--before /workspace/old.conf \
--after /workspace/new.conf \
-o /workspace/diff_result.json
Docker run options summary
| Option | Description |
|--------|-------------|
| --rm | Remove the container after the run (recommended). |
| -v $(pwd):/workspace | Mount current directory; config and report paths use your local files. |
| -v /tmp:/tmp | Mount /tmp (optional) for output to host's /tmp. |
| -c file.conf | Config path (relative to /workspace when mounted). |
| -o /workspace/report.html | Output path; use /workspace/ to write to current directory. |
Usage
FortiCheck runs entirely offline. You only need a configuration backup file (.conf) from your FortiGate device.
Commands
| Command | Description |
|---------|-------------|
| forticheck analyze -c CONFIG [options] | Analyze a FortiGate config and produce an HTML and/or JSON report. |
| forticheck diff --before OLD --after NEW [-o OUTPUT] | Compare two configs and output a JSON diff of policies. |
| forticheck --help | Show main help. |
| forticheck analyze --help | Show all analyze options. |
Basic analysis
forticheck analyze -c /path/to/fortigate.conf
By default, the report is saved as {config_filename}_{date}_{time}.html in the current directory (e.g. fortigate_2025-02-13_143022.html).
Analyze options (summary)
| Option | Short | Description |
|--------|-------|-------------|
| --config | -c | Path to FortiGate config file (required). |
| --output | -o | Report file path. Default: {config_stem}_{YYYY-MM-DD_HHMMSS}.html. |
| --format | -f | html, json, or both. Default: html. |
| --zones-trust | -z | YAML file with zone trust levels (0–100). |
| --rules | -r | YAML file with custom rules (forbid_service, require_security_profile). |
| --min-severity | | Only include findings with this severity or higher: info, low, medium, high, critical. |
| --verbose | -v | Enable verbose logging. |
Advanced usage examples
# HTML + JSON to a specific path
forticheck analyze -c fw.conf -o ./reports/audit_results.html -f both
# Verbose logging for debugging
forticheck analyze -c fw.conf -v
# Custom zone trust levels (improves risk scoring)
forticheck analyze -c fw.conf --zones-trust trust_levels.yaml
# Custom security rules
forticheck analyze -c fw.conf --rules custom_rules.yaml
# Only medium-and-above findings in the report
forticheck analyze -c fw.conf --min-severity medium
Config diff
Compare two configuration files (policy add/remove/change):
forticheck diff --before old.conf --after new.conf -o forticheck_diff.json
Custom Zone Trust (trust_levels.yaml)
Define the trust level (0-100) for your zones to improve analysis accuracy. You can use either a simple zone_name: value format or an object with trust_level:
zones:
internet: 0
dmz: 30
guest: 10
lan: 90
servers: 100
# Alternative format: zone_name: { trust_level: 50 }
If the file is missing or invalid, FortiCheck uses built-in default trust levels and continues the analysis.
Custom Rules (custom_rules.yaml)
Optional. Define your own checks (e.g. forbid RDP between zones, require security profiles):
rules:
- id: R1
type: forbid_service
zones: [dmz, lan]
service: RDP
severity: high
- id: R2
type: require_security_profile
zones: [wan, lan]
severity: medium
Report Sample
The HTML report provides:
- Executive Dashboard: Risk score, critical finding count, and compliance summary.
- Attack Path Visualization: Visual representation of how an attacker could move laterally.
- Detailed Findings: Actionable remediation steps for every issue.
- VPN & User Audit: Dedicated sections for remote access security.

| Executive Summary & Risk Dashboard | Zone Exposure Matrix | CIS Benchmark |
|-----------------------------------|----------------------|---------------|
|
|
|
|

Architecture
FortiCheck processes configurations in 8 layers:
- Parsing: Converts raw config to AST.
- Normalization: Builds a vendor-neutral canonical model.
- Topology: Maps interfaces, routes, and zones into a network graph.
- Logic: Mathematical analysis of policy sets (intersection/subset).
- Exposure: Zone-to-zone reachability analysis.
- Simulation: BFS/DFS based attack path discovery.
- Scoring: Multi-factor risk calculation.
- Reporting: Jinja2-based HTML generation.
Development
make install-dev # Install with dev dependencies
make test # Run tests
make lint # Run ruff
make typecheck # Run mypy
make clean # Remove build artifacts, caches (.pytest_cache, .ruff_cache, etc.)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request on GitHub.
Developer
- Name: Cuma KURT
- Email: [cumakurt@gm
Related Skills
diffs
339.3kUse the diffs tool to produce real, shareable diffs (viewer URL, file artifact, or both) instead of manual edit summaries.
openpencil
1.8kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
ui-ux-pro-max-skill
53.4kAn AI SKILL that provide design intelligence for building professional UI/UX multiple platforms
Figma-Context-MCP
14.0kMCP server to provide Figma layout information to AI coding agents like Cursor
