Skip to main content

Database Configuration

AutoPentestX uses SQLite to store scan results, vulnerabilities, exploits, and historical data. All scan data is persisted to enable reporting, analysis, and audit trails.

Database Location

Default database path (configurable in config.json):
autopentestx/
└── database/
    └── autopentestx.db

Configuration Options

database.type
string
default:"sqlite"
Database type (currently only SQLite is supported)
database.path
string
default:"database/autopentestx.db"
Path to SQLite database file (relative or absolute)
database.backup_enabled
boolean
default:true
Enable automatic database backups before modifications
database.retention_days
integer
default:90
Number of days to retain scan data (0 = keep forever)

Database Schema

AutoPentestX creates five main tables to store scan data:

1. Scans Table

Stores high-level scan metadata and results.
CREATE TABLE scans (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    target TEXT NOT NULL,
    scan_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    os_detection TEXT,
    scan_duration REAL,
    total_ports INTEGER,
    open_ports INTEGER,
    vulnerabilities_found INTEGER,
    risk_score TEXT,
    status TEXT DEFAULT 'completed'
)

Column Descriptions

id
INTEGER
Unique scan identifier (auto-incremented)
target
TEXT
Target IP address or domain name
scan_date
TIMESTAMP
Timestamp when scan was initiated
os_detection
TEXT
Detected operating system from fingerprinting
scan_duration
REAL
Total scan duration in seconds
total_ports
INTEGER
Total number of ports scanned
open_ports
INTEGER
Number of open ports discovered
vulnerabilities_found
INTEGER
Total vulnerabilities identified
risk_score
TEXT
Overall risk level: CRITICAL, HIGH, MEDIUM, LOW, or INFO
status
TEXT
Scan status: completed, in_progress, interrupted, or failed

2. Ports Table

Stores information about discovered ports and services.
CREATE TABLE ports (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    scan_id INTEGER,
    port_number INTEGER,
    protocol TEXT,
    state TEXT,
    service_name TEXT,
    service_version TEXT,
    FOREIGN KEY (scan_id) REFERENCES scans(id)
)

Column Descriptions

scan_id
INTEGER
Foreign key reference to parent scan
port_number
INTEGER
Port number (1-65535)
protocol
TEXT
Protocol: tcp or udp
state
TEXT
Port state: open, closed, or filtered
service_name
TEXT
Detected service name (e.g., http, ssh, mysql)
service_version
TEXT
Service version string if detected

3. Vulnerabilities Table

Stores vulnerability findings and CVE data.
CREATE TABLE vulnerabilities (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    scan_id INTEGER,
    port_number INTEGER,
    service_name TEXT,
    vuln_name TEXT,
    vuln_description TEXT,
    cve_id TEXT,
    cvss_score REAL,
    risk_level TEXT,
    exploitable BOOLEAN,
    FOREIGN KEY (scan_id) REFERENCES scans(id)
)

Column Descriptions

vuln_name
TEXT
Vulnerability name or title
vuln_description
TEXT
Detailed description of the vulnerability
cve_id
TEXT
CVE identifier (e.g., CVE-2024-1234)
cvss_score
REAL
CVSS score (0.0 - 10.0)
risk_level
TEXT
Risk classification: CRITICAL, HIGH, MEDIUM, LOW, or UNKNOWN
exploitable
BOOLEAN
Whether known exploits exist (1 = yes, 0 = no)

4. Web Vulnerabilities Table

Stores web-specific vulnerabilities from Nikto and SQLMap.
CREATE TABLE web_vulnerabilities (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    scan_id INTEGER,
    url TEXT,
    vuln_type TEXT,
    severity TEXT,
    description TEXT,
    FOREIGN KEY (scan_id) REFERENCES scans(id)
)

Column Descriptions

url
TEXT
Full URL where vulnerability was discovered
vuln_type
TEXT
Vulnerability type (e.g., XSS, SQL Injection, Directory Listing)
severity
TEXT
Severity level: HIGH, MEDIUM, or LOW

5. Exploits Table

Stores exploitation attempts and results.
CREATE TABLE exploits (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    scan_id INTEGER,
    vuln_id INTEGER,
    exploit_name TEXT,
    exploit_status TEXT,
    exploit_result TEXT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (scan_id) REFERENCES scans(id),
    FOREIGN KEY (vuln_id) REFERENCES vulnerabilities(id)
)

Column Descriptions

vuln_id
INTEGER
Foreign key reference to vulnerability being exploited
exploit_name
TEXT
Name of exploit module or technique
exploit_status
TEXT
Status: success, failed, or simulated
exploit_result
TEXT
JSON-encoded exploit result data

Database Operations

The Database class in modules/database.py provides methods for all database operations:

Initialization

from modules.database import Database

# Initialize with default path
db = Database()

# Or specify custom path
db = Database(db_path="/custom/path/pentest.db")

Creating a Scan

# Insert new scan record
scan_id = db.insert_scan(
    target="192.168.1.100",
    os_detection="Linux 5.x"
)

Updating Scan Results

# Update scan with results
db.update_scan(
    scan_id=scan_id,
    total_ports=65535,
    open_ports=5,
    vulnerabilities_found=12,
    risk_score="HIGH",
    scan_duration=1234.56,
    status="completed"
)

Inserting Port Data

port_data = {
    'port': 80,
    'protocol': 'tcp',
    'state': 'open',
    'service': 'http',
    'version': 'Apache 2.4.41'
}
db.insert_port(scan_id, port_data)

Inserting Vulnerabilities

vuln_data = {
    'port': 80,
    'service': 'http',
    'name': 'Outdated Apache Version',
    'description': 'Apache 2.4.41 has known vulnerabilities',
    'cve_id': 'CVE-2024-1234',
    'cvss_score': 7.5,
    'risk_level': 'HIGH',
    'exploitable': True
}
vuln_id = db.insert_vulnerability(scan_id, vuln_data)

Retrieving Scan Data

# Get complete scan data
scan_data = db.get_scan_data(scan_id)

print(scan_data['scan'])              # Scan metadata
print(scan_data['ports'])             # All ports
print(scan_data['vulnerabilities'])   # All vulnerabilities
print(scan_data['web_vulnerabilities']) # Web vulns
print(scan_data['exploits'])          # Exploit attempts

Listing All Scans

# Get all scans (ordered by date, newest first)
all_scans = db.get_all_scans()

for scan in all_scans:
    print(f"Scan ID: {scan[0]}, Target: {scan[1]}, Date: {scan[2]}")

Querying the Database

You can query the database directly using SQLite tools:
# Open database with sqlite3
sqlite3 database/autopentestx.db

# View all scans
SELECT * FROM scans;

# View vulnerabilities for scan ID 5
SELECT * FROM vulnerabilities WHERE scan_id = 5;

# Count total vulnerabilities by risk level
SELECT risk_level, COUNT(*) 
FROM vulnerabilities 
GROUP BY risk_level;

Useful SQL Queries

Find High-Risk Scans

SELECT id, target, scan_date, risk_score, vulnerabilities_found
FROM scans
WHERE risk_score IN ('CRITICAL', 'HIGH')
ORDER BY scan_date DESC;

Get All Vulnerabilities for a Target

SELECT v.vuln_name, v.cve_id, v.cvss_score, v.risk_level
FROM vulnerabilities v
JOIN scans s ON v.scan_id = s.id
WHERE s.target = '192.168.1.100'
ORDER BY v.cvss_score DESC;

Count Exploitable Vulnerabilities

SELECT s.target, COUNT(*) as exploitable_count
FROM vulnerabilities v
JOIN scans s ON v.scan_id = s.id
WHERE v.exploitable = 1
GROUP BY s.target;

View Open Ports Across All Scans

SELECT s.target, p.port_number, p.service_name, p.service_version
FROM ports p
JOIN scans s ON p.scan_id = s.id
WHERE p.state = 'open'
ORDER BY s.target, p.port_number;

Backup and Maintenance

Manual Backup

# Create timestamped backup
cp database/autopentestx.db database/autopentestx_$(date +%Y%m%d_%H%M%S).db

Database Cleanup

The retention_days setting automatically removes old scans. Set to 0 to keep all data indefinitely.
-- Manually delete scans older than 90 days
DELETE FROM scans
WHERE scan_date < datetime('now', '-90 days');

-- Vacuum database to reclaim space
VACUUM;

Optimize Database

-- Analyze tables for query optimization
ANALYZE;

-- Rebuild indexes
REINDEX;

Data Export

Export to CSV

sqlite3 database/autopentestx.db <<EOF
.headers on
.mode csv
.output scans_export.csv
SELECT * FROM scans;
.quit
EOF

Export to JSON

sqlite3 database/autopentestx.db <<EOF
.mode json
.output scan_data.json
SELECT * FROM scans;
.quit
EOF

Database Connection Management

The Database class automatically:
  • Creates the database file if it doesn’t exist
  • Creates all tables on first connection
  • Handles connection errors gracefully
  • Commits transactions after each operation
# Database class handles connection lifecycle
db = Database()  # Connects automatically

# Perform operations...
db.insert_scan(target="192.168.1.1")

# Always close when done
db.close()
Always call db.close() when finished to prevent database locks and ensure data integrity.

Error Handling

Common database errors and solutions:
ErrorCauseSolution
database is lockedMultiple processes accessing databaseClose other connections, wait and retry
unable to open database fileIncorrect path or permissionsCheck path and file permissions
no such tableTables not createdEnsure create_tables() was called
FOREIGN KEY constraint failedInvalid reference IDVerify parent record exists

Build docs developers (and LLMs) love