docs(tools): add README for security tools (#5164)

* docs(tools): add README + comprehensive tests for security tools

READMEs added for 7 security scanning tools:
- port_scanner: TCP connect scans, banner grabbing, risky port detection
- ssl_tls_scanner: TLS version, cipher, certificate analysis
- http_headers_scanner: OWASP security headers validation
- dns_security_scanner: SPF, DMARC, DKIM, DNSSEC, zone transfer
- subdomain_enumerator: Passive CT log subdomain discovery
- tech_stack_detector: Web technology fingerprinting
- risk_scorer: Weighted letter-grade risk scoring

Comprehensive unit tests (92 total):
- Port scanner: constants, port categories, _check_port async tests
- SSL/TLS scanner: weak ciphers, TLS versions, cert parsing helpers
- HTTP headers scanner: security headers, leaky headers validation
- DNS security scanner: SPF/DMARC/DKIM/DNSSEC checks
- Subdomain enumerator: keyword detection, severity levels
- Tech stack detector: cookies, CDN, CMS, framework detection
- Risk scorer: grading logic, category scoring, JSON parsing

Fixes #5094

* revert: remove test changes per review feedback
This commit is contained in:
Emmanuel Nwanguma
2026-02-23 14:46:51 +01:00
committed by GitHub
parent 005609da3a
commit 002da15375
7 changed files with 824 additions and 0 deletions
@@ -0,0 +1,111 @@
# DNS Security Scanner Tool
Check SPF, DMARC, DKIM, DNSSEC configuration and zone transfer vulnerability.
## Features
- **dns_security_scan** - Evaluate email security and DNS infrastructure hardening
## How It Works
Performs non-intrusive DNS queries to check:
1. SPF record presence and policy strength
2. DMARC record presence and enforcement level
3. DKIM selectors (probes common selectors)
4. DNSSEC enablement
5. MX and CAA records
6. Zone transfer vulnerability (AXFR)
**Requires dnspython** - Install with `pip install dnspython`
## Usage Examples
### Basic Scan
```python
dns_security_scan(domain="example.com")
```
## API Reference
### dns_security_scan
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| domain | str | Yes | Domain name to scan (e.g., "example.com") |
### Response
```json
{
"domain": "example.com",
"spf": {
"present": true,
"record": "v=spf1 include:_spf.google.com -all",
"policy": "hardfail",
"issues": []
},
"dmarc": {
"present": true,
"record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
"policy": "reject",
"issues": []
},
"dkim": {
"selectors_found": ["google", "selector1"],
"selectors_missing": ["default", "k1", "mail"]
},
"dnssec": {
"enabled": true,
"issues": []
},
"mx_records": ["10 mail.example.com"],
"caa_records": ["0 issue \"letsencrypt.org\""],
"zone_transfer": {
"vulnerable": false
},
"grade_input": {
"spf_present": true,
"spf_strict": true,
"dmarc_present": true,
"dmarc_enforcing": true,
"dkim_found": true,
"dnssec_enabled": true,
"zone_transfer_blocked": true
}
}
```
## Security Checks
| Check | Severity | Description |
|-------|----------|-------------|
| No SPF record | High | Any server can spoof emails |
| SPF softfail (~all) | Medium | Spoofed emails may be delivered |
| SPF +all | Critical | Effectively disables SPF |
| No DMARC record | High | Email spoofing not blocked |
| DMARC p=none | Medium | Monitoring only, no enforcement |
| No DKIM | Medium | Emails cannot be cryptographically verified |
| DNSSEC disabled | Medium | Vulnerable to DNS spoofing |
| Zone transfer allowed | Critical | Full DNS zone can be downloaded |
## DKIM Selectors Probed
The tool checks these common DKIM selectors:
- `default`, `google`, `selector1`, `selector2`
- `k1`, `mail`, `dkim`, `s1`
## Ethical Use
⚠️ **Important**: Only scan domains you own or have explicit permission to test.
- DNS queries are generally non-intrusive
- Zone transfer tests may be logged by DNS providers
## Error Handling
```python
{"error": "dnspython is not installed. Install it with: pip install dnspython"}
{"error": "Could not resolve NS records"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.
@@ -0,0 +1,111 @@
# HTTP Headers Scanner Tool
Check OWASP-recommended security headers and detect information leakage.
## Features
- **http_headers_scan** - Evaluate response headers against OWASP Secure Headers Project guidelines
## How It Works
Sends a single GET request and analyzes response headers:
1. Checks for presence of security headers (HSTS, CSP, X-Frame-Options, etc.)
2. Identifies missing headers with remediation guidance
3. Detects information-leaking headers (Server, X-Powered-By)
**No credentials required** - Uses only standard HTTP requests.
## Usage Examples
### Basic Scan
```python
http_headers_scan(url="https://example.com")
```
### Without Following Redirects
```python
http_headers_scan(
url="https://example.com",
follow_redirects=False
)
```
## API Reference
### http_headers_scan
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| url | str | Yes | - | Full URL to scan (auto-prefixes https://) |
| follow_redirects | bool | No | True | Whether to follow HTTP redirects |
### Response
```json
{
"url": "https://example.com/",
"status_code": 200,
"headers_present": [
"Strict-Transport-Security",
"X-Content-Type-Options"
],
"headers_missing": [
{
"header": "Content-Security-Policy",
"severity": "high",
"description": "No CSP header. The site is more vulnerable to XSS attacks.",
"remediation": "Add a Content-Security-Policy header. Start restrictive: default-src 'self'"
}
],
"leaky_headers": [
{
"header": "Server",
"value": "nginx/1.18.0",
"severity": "low",
"remediation": "Remove or genericize the Server header to avoid version disclosure."
}
],
"grade_input": {
"hsts": true,
"csp": false,
"x_frame_options": true,
"x_content_type_options": true,
"referrer_policy": false,
"permissions_policy": false,
"no_leaky_headers": false
}
}
```
## Security Headers Checked
| Header | Severity | Purpose |
|--------|----------|---------|
| Strict-Transport-Security | High | Enforces HTTPS connections |
| Content-Security-Policy | High | Prevents XSS attacks |
| X-Frame-Options | Medium | Prevents clickjacking |
| X-Content-Type-Options | Medium | Prevents MIME sniffing |
| Referrer-Policy | Low | Controls referrer information |
| Permissions-Policy | Low | Restricts browser features |
## Leaky Headers Detected
| Header | Risk |
|--------|------|
| Server | Reveals web server and version |
| X-Powered-By | Reveals backend framework |
| X-AspNet-Version | Reveals ASP.NET version |
| X-Generator | Reveals CMS/platform |
## Ethical Use
⚠️ **Important**: Only scan systems you own or have explicit permission to test.
## Error Handling
```python
{"error": "Connection failed: [details]"}
{"error": "Request to https://example.com timed out"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.
@@ -0,0 +1,118 @@
# Port Scanner Tool
Scan common ports and detect exposed services using non-intrusive TCP connect probes.
## Features
- **port_scan** - Scan a host for open ports, grab service banners, and flag risky exposures
## How It Works
Performs TCP connect scans using Python's asyncio. The scanner:
1. Attempts to establish a TCP connection to each port
2. Grabs service banners where available
3. Identifies the service type (HTTP, SSH, MySQL, etc.)
4. Flags security risks (exposed databases, admin interfaces, legacy protocols)
**No credentials required** - Uses only standard network connections.
## Usage Examples
### Scan Top 20 Common Ports
```python
port_scan(
hostname="example.com",
ports="top20"
)
```
### Scan Top 100 Ports
```python
port_scan(
hostname="example.com",
ports="top100",
timeout=5.0
)
```
### Scan Specific Ports
```python
port_scan(
hostname="example.com",
ports="80,443,8080,3306,5432"
)
```
## API Reference
### port_scan
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| hostname | str | Yes | - | Domain or IP to scan (e.g., "example.com") |
| ports | str | No | "top20" | Ports to scan: "top20", "top100", or comma-separated list |
| timeout | float | No | 3.0 | Connection timeout per port in seconds (max 10.0) |
### Response
```json
{
"hostname": "example.com",
"ip": "93.184.216.34",
"ports_scanned": 20,
"open_ports": [
{
"port": 80,
"service": "HTTP",
"banner": "nginx/1.18.0"
},
{
"port": 443,
"service": "HTTPS",
"banner": ""
},
{
"port": 3306,
"service": "MySQL",
"banner": "",
"severity": "high",
"finding": "MySQL port (3306) exposed to internet",
"remediation": "Restrict database ports to localhost or VPN only."
}
],
"closed_ports": [21, 22, 23, ...],
"grade_input": {
"no_database_ports_exposed": false,
"no_admin_ports_exposed": true,
"no_legacy_ports_exposed": true,
"only_web_ports": false
}
}
```
## Security Findings
The scanner flags three categories of risky ports:
| Category | Ports | Severity |
|----------|-------|----------|
| Database | 1433 (MSSQL), 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis), 27017 (MongoDB) | High |
| Admin/Remote | 3389 (RDP), 5900 (VNC), 2082-2087 (cPanel) | High |
| Legacy | 21 (FTP), 23 (Telnet), 110 (POP3), 143 (IMAP), 445 (SMB) | Medium |
## Ethical Use
⚠️ **Important**: Only scan systems you own or have explicit permission to test.
- This tool performs active network connections
- Unauthorized port scanning may violate laws and terms of service
- Use responsibly for security assessments of your own infrastructure
## Error Handling
```python
{"error": "Could not resolve hostname: invalid.domain"}
{"error": "Invalid port list: abc. Use 'top20', 'top100', or '80,443'"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.
@@ -0,0 +1,156 @@
# Risk Scorer Tool
Calculate weighted letter-grade risk scores from security scan results.
## Features
- **risk_score** - Aggregate findings from all scanning tools into A-F grades per category and overall
## How It Works
Consumes `grade_input` from the 6 scanning tools and produces:
1. Per-category scores (0-100) and letter grades (A-F)
2. Weighted overall score based on category importance
3. Top 10 risks sorted by severity
4. Handles missing scans gracefully (redistributes weight)
**Pure Python** - No external dependencies.
## Usage Examples
### Score All Scan Results
```python
risk_score(
ssl_results='{"grade_input": {"tls_version_ok": true, ...}}',
headers_results='{"grade_input": {"hsts": true, ...}}',
dns_results='{"grade_input": {"spf_present": true, ...}}',
ports_results='{"grade_input": {"no_database_ports_exposed": true, ...}}',
tech_results='{"grade_input": {"server_version_hidden": false, ...}}',
subdomain_results='{"grade_input": {"no_dev_staging_exposed": true, ...}}'
)
```
### Partial Scan (Some Categories Skipped)
```python
# Only SSL and headers scanned
risk_score(
ssl_results='{"grade_input": {...}}',
headers_results='{"grade_input": {...}}'
)
```
## API Reference
### risk_score
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| ssl_results | str | No | JSON string from ssl_tls_scan |
| headers_results | str | No | JSON string from http_headers_scan |
| dns_results | str | No | JSON string from dns_security_scan |
| ports_results | str | No | JSON string from port_scan |
| tech_results | str | No | JSON string from tech_stack_detect |
| subdomain_results | str | No | JSON string from subdomain_enumerate |
### Response
```json
{
"overall_score": 72,
"overall_grade": "C",
"categories": {
"ssl_tls": {
"score": 85,
"grade": "B",
"weight": 0.20,
"findings_count": 1,
"skipped": false
},
"http_headers": {
"score": 60,
"grade": "C",
"weight": 0.20,
"findings_count": 3,
"skipped": false
},
"dns_security": {
"score": null,
"grade": "N/A",
"weight": 0.15,
"findings_count": 0,
"skipped": true
}
},
"top_risks": [
"Missing Content-Security-Policy header (Http Headers: C)",
"No DMARC record found (Dns Security: D)",
"Database port(s) exposed to internet (Network Exposure: D)"
],
"grade_scale": {
"A": "90-100: Excellent security posture",
"B": "75-89: Good, minor improvements needed",
"C": "60-74: Fair, notable security gaps",
"D": "40-59: Poor, significant vulnerabilities",
"F": "0-39: Critical, immediate action required"
}
}
```
## Grade Scale
| Grade | Score | Meaning |
|-------|-------|---------|
| A | 90-100 | Excellent security posture |
| B | 75-89 | Good, minor improvements needed |
| C | 60-74 | Fair, notable security gaps |
| D | 40-59 | Poor, significant vulnerabilities |
| F | 0-39 | Critical, immediate action required |
## Category Weights
| Category | Weight | Source Tool |
|----------|--------|-------------|
| SSL/TLS | 20% | ssl_tls_scan |
| HTTP Headers | 20% | http_headers_scan |
| DNS Security | 15% | dns_security_scan |
| Network Exposure | 15% | port_scan |
| Technology | 15% | tech_stack_detect |
| Attack Surface | 15% | subdomain_enumerate |
## Scoring Logic
Each category has specific checks worth points:
- Passing a check earns full points
- Failing a check earns zero points and adds a finding
- Missing data (scan not run) earns half credit
The overall score is a weighted average of category scores, normalized if some categories were skipped.
## Workflow Example
```python
# 1. Run all scans
ssl = ssl_tls_scan("example.com")
headers = http_headers_scan("https://example.com")
dns = dns_security_scan("example.com")
ports = port_scan("example.com")
tech = tech_stack_detect("https://example.com")
subs = subdomain_enumerate("example.com")
# 2. Calculate risk score
import json
score = risk_score(
ssl_results=json.dumps(ssl),
headers_results=json.dumps(headers),
dns_results=json.dumps(dns),
ports_results=json.dumps(ports),
tech_results=json.dumps(tech),
subdomain_results=json.dumps(subs)
)
# 3. Review results
print(f"Overall Grade: {score['overall_grade']}")
print(f"Top Risks: {score['top_risks']}")
```
## Error Handling
Invalid JSON inputs are treated as skipped categories (grade = N/A).
@@ -0,0 +1,96 @@
# SSL/TLS Scanner Tool
Analyze SSL/TLS configuration and certificate security for any HTTPS endpoint.
## Features
- **ssl_tls_scan** - Check TLS version, cipher suite, certificate validity, and common misconfigurations
## How It Works
Performs non-intrusive TLS handshake analysis using Python's ssl module:
1. Establishes a TLS connection to the target
2. Extracts certificate details (issuer, expiry, SANs)
3. Checks TLS version and cipher strength
4. Identifies security issues and misconfigurations
**No credentials required** - Uses only Python stdlib (ssl + socket).
## Usage Examples
### Basic Scan
```python
ssl_tls_scan(hostname="example.com")
```
### Scan Non-Standard Port
```python
ssl_tls_scan(hostname="example.com", port=8443)
```
## API Reference
### ssl_tls_scan
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| hostname | str | Yes | - | Domain name to scan (e.g., "example.com") |
| port | int | No | 443 | Port to connect to |
### Response
```json
{
"hostname": "example.com",
"port": 443,
"tls_version": "TLSv1.3",
"cipher": "TLS_AES_256_GCM_SHA384",
"cipher_bits": 256,
"certificate": {
"subject": "CN=example.com",
"issuer": "CN=R3, O=Let's Encrypt, C=US",
"not_before": "2024-01-01T00:00:00+00:00",
"not_after": "2024-04-01T00:00:00+00:00",
"days_until_expiry": 45,
"san": ["example.com", "www.example.com"],
"self_signed": false,
"sha256_fingerprint": "abc123..."
},
"issues": [],
"grade_input": {
"tls_version_ok": true,
"cert_valid": true,
"cert_expiring_soon": false,
"strong_cipher": true,
"self_signed": false
}
}
```
## Security Checks
| Check | Severity | Description |
|-------|----------|-------------|
| Insecure TLS version | High | TLS 1.0, 1.1, SSLv2, SSLv3 are vulnerable |
| Weak cipher suite | High | RC4, DES, 3DES, MD5, NULL, EXPORT ciphers |
| Certificate expired | Critical | SSL certificate has expired |
| Certificate expiring soon | Medium | Expires within 30 days |
| Self-signed certificate | High | Not trusted by browsers |
| Verification failed | Critical | Certificate chain validation failed |
## Ethical Use
⚠️ **Important**: Only scan systems you own or have explicit permission to test.
- This tool performs active TLS connections
- Scanning third-party sites without permission may violate terms of service
## Error Handling
```python
{"error": "Connection to example.com:443 timed out"}
{"error": "Connection to example.com:443 refused. Port may be closed."}
{"error": "Connection failed: [SSL error details]"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.
@@ -0,0 +1,110 @@
# Subdomain Enumerator Tool
Discover subdomains via Certificate Transparency (CT) logs using passive OSINT.
## Features
- **subdomain_enumerate** - Find subdomains from public CT log data and flag sensitive environments
## How It Works
Queries crt.sh (Certificate Transparency log aggregator) to discover subdomains:
1. Fetches all certificates issued for the domain
2. Extracts subdomain names from certificate SANs
3. Identifies potentially sensitive subdomains (staging, dev, admin, etc.)
**Fully passive** - No active DNS enumeration or brute-forcing.
## Usage Examples
### Basic Enumeration
```python
subdomain_enumerate(domain="example.com")
```
### Limit Results
```python
subdomain_enumerate(
domain="example.com",
max_results=100
)
```
## API Reference
### subdomain_enumerate
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| domain | str | Yes | - | Base domain to enumerate |
| max_results | int | No | 50 | Maximum subdomains to return (max 200) |
### Response
```json
{
"domain": "example.com",
"source": "crt.sh (Certificate Transparency)",
"total_found": 25,
"subdomains": [
"www.example.com",
"api.example.com",
"staging.example.com",
"mail.example.com"
],
"interesting": [
{
"subdomain": "staging.example.com",
"reason": "Staging environment exposed publicly",
"severity": "medium",
"remediation": "Restrict staging to VPN or internal network access."
},
{
"subdomain": "admin.example.com",
"reason": "Admin panel subdomain exposed publicly",
"severity": "high",
"remediation": "Restrict admin panels to VPN or trusted IP ranges."
}
],
"grade_input": {
"no_dev_staging_exposed": false,
"no_admin_exposed": false,
"reasonable_surface_area": true
}
}
```
## Sensitive Subdomain Detection
| Keyword | Severity | Risk |
|---------|----------|------|
| admin | High | Admin panel exposed |
| backup | High | Backup infrastructure exposed |
| debug | High | Debug endpoints exposed |
| staging | Medium | Staging environment exposed |
| dev | Medium | Development environment exposed |
| test | Medium | Test environment exposed |
| internal | Medium | Internal systems in CT logs |
| ftp | Medium | Legacy FTP service |
| vpn | Low | VPN endpoint discoverable |
| api | Low | API attack surface |
| mail | Info | Mail server (check SPF/DKIM/DMARC) |
## Ethical Use
⚠️ **Important**:
- This tool uses only public Certificate Transparency data
- CT logs are public by design (browser transparency requirement)
- Still, only enumerate domains you have authorization to assess
- Discovery of subdomains does not grant permission to test them
## Error Handling
```python
{"error": "crt.sh returned HTTP 503", "domain": "example.com"}
{"error": "crt.sh request timed out (try again later)", "domain": "example.com"}
{"error": "CT log query failed: [details]", "domain": "example.com"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.
@@ -0,0 +1,122 @@
# Tech Stack Detector Tool
Fingerprint web technologies through passive HTTP analysis.
## Features
- **tech_stack_detect** - Identify web server, framework, CMS, JavaScript libraries, CDN, and security configuration
## How It Works
Performs non-intrusive HTTP requests to identify technologies:
1. Analyzes response headers (Server, X-Powered-By)
2. Parses HTML for JS libraries, frameworks, and CMS signatures
3. Inspects cookies for backend technology hints
4. Probes common paths (wp-admin, security.txt, etc.)
5. Detects CDN and analytics services
**No credentials required** - Uses only standard HTTP requests.
## Usage Examples
### Basic Detection
```python
tech_stack_detect(url="https://example.com")
```
## API Reference
### tech_stack_detect
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| url | str | Yes | URL to analyze (auto-prefixes https://) |
### Response
```json
{
"url": "https://example.com/",
"server": {
"name": "nginx",
"version": "1.18.0",
"raw": "nginx/1.18.0"
},
"framework": "Express",
"language": "Node.js",
"cms": "WordPress",
"javascript_libraries": ["React", "jQuery 3.6.0"],
"cdn": "Cloudflare",
"analytics": ["Google Analytics"],
"security_txt": true,
"robots_txt": true,
"interesting_paths": ["/api/", "/admin/"],
"cookies": [
{
"name": "session",
"secure": true,
"httponly": true,
"samesite": "Strict"
}
],
"grade_input": {
"server_version_hidden": false,
"framework_version_hidden": true,
"security_txt_present": true,
"cookies_secure": true,
"cookies_httponly": true
}
}
```
## Technologies Detected
### Web Servers
nginx, Apache, IIS, LiteSpeed, etc.
### Frameworks & Languages
- **PHP**: Laravel, WordPress, Drupal
- **Python**: Django, Flask
- **JavaScript**: Express, Next.js, Nuxt.js
- **Ruby**: Rails
- **Java**: Spring
- **.NET**: ASP.NET
### JavaScript Libraries
React, Angular, Vue.js, jQuery, Bootstrap, Tailwind CSS, Svelte
### CMS Platforms
WordPress, Drupal, Joomla, Shopify, Squarespace, Wix, Ghost
### CDN Providers
Cloudflare, AWS CloudFront, Fastly, Akamai, Vercel, Netlify
### Analytics
Google Analytics, Facebook Pixel, Hotjar, Mixpanel, Segment
## Security Checks
| Check | Risk |
|-------|------|
| Server version disclosed | Enables targeted exploits |
| Framework version disclosed | Enables targeted exploits |
| No security.txt | No vulnerability reporting channel |
| Cookies missing Secure flag | Transmitted over HTTP |
| Cookies missing HttpOnly flag | Accessible to JavaScript (XSS risk) |
## Ethical Use
⚠️ **Important**: Only scan systems you own or have explicit permission to test.
- This tool sends multiple HTTP requests
- Path probing may be logged by the target
## Error Handling
```python
{"error": "Connection failed: [details]"}
{"error": "Request to https://example.com timed out"}
{"error": "Detection failed: [details]"}
```
## Integration with Risk Scorer
The `grade_input` field can be passed to the `risk_score` tool for weighted security grading.