offsec-ai 2.0.0__tar.gz → 2.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/CHANGELOG.md +18 -1
  2. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/CONTRIBUTING.md +4 -4
  3. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/LICENSE +1 -1
  4. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/PKG-INFO +30 -6
  5. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/README.md +24 -3
  6. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/SECURITY.md +5 -5
  7. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/DOCKER.md +110 -9
  8. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/assets/logo.svg +1 -1
  9. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/quickstart.md +6 -6
  10. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/pyproject.toml +6 -3
  11. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/__init__.py +1 -1
  12. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/ai_owasp_scanner.py +1 -1
  13. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/hybrid_identity_checker.py +1 -1
  14. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/l7_detector.py +1 -1
  15. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/mcp_attacker.py +4 -4
  16. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/mcp_scanner.py +2 -2
  17. offsec_ai-2.0.2/tests/test_mtls.py +102 -0
  18. offsec_ai-2.0.2/tests/test_mtls_integration.py +82 -0
  19. offsec_ai-2.0.0/tests/test_dns_trace.py +0 -85
  20. offsec_ai-2.0.0/tests/test_mtls.py +0 -159
  21. offsec_ai-2.0.0/tests/test_mtls_integration.py +0 -193
  22. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/.gitignore +0 -0
  23. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/api.md +0 -0
  24. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/azure-ad-flow-explained.md +0 -0
  25. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/hybrid-identity.md +0 -0
  26. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/docs/owasp-scanner.md +0 -0
  27. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/examples/comprehensive_examples.py +0 -0
  28. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/examples/mtls_examples.py +0 -0
  29. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/examples/owasp_scan_examples.py +0 -0
  30. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/examples/usage_examples.py +0 -0
  31. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/__main__.py +0 -0
  32. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/cli.py +0 -0
  33. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/__init__.py +0 -0
  34. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/cert_analyzer.py +0 -0
  35. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/llm_judge.py +0 -0
  36. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/mtls_checker.py +0 -0
  37. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/owasp_scanner.py +0 -0
  38. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/port_scanner.py +0 -0
  39. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/core/security_headers.py +0 -0
  40. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/__init__.py +0 -0
  41. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/ai_owasp_result.py +0 -0
  42. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/l7_result.py +0 -0
  43. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/mcp_result.py +0 -0
  44. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/mtls_result.py +0 -0
  45. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/owasp_result.py +0 -0
  46. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/models/scan_result.py +0 -0
  47. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/py.typed +0 -0
  48. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/__init__.py +0 -0
  49. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/ai_owasp_payloads.py +0 -0
  50. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/ai_owasp_remediation.py +0 -0
  51. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/common_ports.py +0 -0
  52. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/exporters.py +0 -0
  53. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/l7_signatures.py +0 -0
  54. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/mcp_cve_db.py +0 -0
  55. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/mcp_payloads.py +0 -0
  56. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/src/offsec_ai/utils/owasp_remediation.py +0 -0
  57. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/tests/conftest.py +0 -0
  58. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/tests/test_ai_owasp.py +0 -0
  59. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/tests/test_mcp_attacker.py +0 -0
  60. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/tests/test_mcp_scanner.py +0 -0
  61. {offsec_ai-2.0.0 → offsec_ai-2.0.2}/tests/test_port_scanner.py +0 -0
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.2] - 2026-06-29
9
+
10
+ ### Changed
11
+ - README logo replaced with inline ASCII art (no external image dependency)
12
+ - User-Agent strings updated from `SimplePortChecker/1.0` to `offsec-ai/2.0` in `L7Detector` and `HybridIdentityChecker`
13
+ - `reportlab>=4.0.0` promoted to core dependency in `pyproject.toml` (was missing, caused `ModuleNotFoundError` on fresh installs)
14
+ - Docker image now installs `[ai]` extras (`openai`, `anthropic`) so LLM judge works at runtime via env vars
15
+ - Dockerfile redundant pre-installs removed; `pip install ".[ai]"` is now the single install step
16
+ - `docker-push` and `docker-release` Makefile targets added with auto-versioning from `pyproject.toml`
17
+ - CI/CD: `docker.yml` image labels updated (title, description); unused `build-args` removed
18
+ - CI/CD: `publish.yml` PyPI environment URL no longer pins a hardcoded version
19
+ - Stale files removed: `PROJECT_STRUCTURE.md`, `HYBRID_IDENTITY_QUICKREF.md`, `IMPLEMENTATION_HYBRID_IDENTITY.md`, `MANIFEST.in`, empty `scripts/` dir
20
+ - `tests/test_dns_trace.py` removed (was a live-network script, not a pytest test)
21
+ - `tests/test_mtls.py` and `tests/test_mtls_integration.py` rewritten as proper `assert`-based pytest tests
22
+ - `setup_dev.sh` updated: branding, venv path (`.venv`), and `[ai]` extras
23
+
8
24
  ## [2.0.0] - 2026-06-29
9
25
 
10
26
  ### Added — AI / LLM Security (fresh start as `offsec-ai`)
@@ -560,5 +576,6 @@ All existing functionality (port scanning, L7 detection, mTLS, certificate analy
560
576
  - cryptography: For certificate handling
561
577
  - certifi: For CA bundle management
562
578
 
563
- [Unreleased]: https://github.com/htunn/offsec-ai/compare/v2.0.0...HEAD
579
+ [Unreleased]: https://github.com/Htunn/offsec-ai/compare/v2.0.1...HEAD
580
+ [2.0.1]: https://github.com/Htunn/offsec-ai/compare/v2.0.0...v2.0.1
564
581
  [2.0.0]: https://github.com/htunn/offsec-ai/releases/tag/v2.0.0
@@ -1,6 +1,6 @@
1
- # Contributing to Simple Port Checker
1
+ # Contributing to offsec-ai
2
2
 
3
- Thank you for your interest in contributing to Simple Port Checker! This guide will help you get started.
3
+ Thank you for your interest in contributing to offsec-ai! This guide will help you get started.
4
4
 
5
5
  ## Code of Conduct
6
6
 
@@ -12,7 +12,7 @@ This project adheres to a code of conduct. By participating, you are expected to
12
12
 
13
13
  1. **Fork and clone the repository**
14
14
  ```bash
15
- git clone https://github.com/yourusername/offsec-ai.git
15
+ git clone https://github.com/Htunn/offsec-ai.git
16
16
  cd offsec-ai
17
17
  ```
18
18
 
@@ -327,4 +327,4 @@ Contributors will be recognized in:
327
327
  - **Release notes** for significant contributions
328
328
  - **GitHub contributors** page
329
329
 
330
- Thank you for contributing to Simple Port Checker! 🎉
330
+ Thank you for contributing to offsec-ai! 🎉
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Simple Port Checker
3
+ Copyright (c) 2026 offsec-ai (Htunn)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,13 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: offsec-ai
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Offensive-security toolkit: port scanning, L7/WAF detection, mTLS, certificate analysis, OWASP Top 10, AI/LLM OWASP Top 10 black-box probing, and MCP endpoint security scanning
5
5
  Project-URL: Homepage, https://github.com/htunn/offsec-ai
6
6
  Project-URL: Repository, https://github.com/htunn/offsec-ai
7
7
  Project-URL: Issues, https://github.com/htunn/offsec-ai/issues
8
8
  Project-URL: Documentation, https://github.com/htunn/offsec-ai#readme
9
- Author-email: htunn <htunnthuthu.linux@gmail.com>
10
- Maintainer-email: htunn <htunnthuthu.linux@gmail.com>
9
+ Author: Htunn
10
+ Author-email: htunnthuthu.linux@gmail.com
11
+ Maintainer: Htunn
12
+ Maintainer-email: htunnthuthu.linux@gmail.com
11
13
  License: MIT
12
14
  License-File: LICENSE
13
15
  Keywords: ai,ai-security,certificate,certificate-analysis,firewall,l7-protection,llm,mcp,model-context-protocol,network,offensive-security,owasp,pentest,pki,port-scanner,red-team,security,ssl,tls,waf
@@ -37,6 +39,7 @@ Requires-Dist: httpx>=0.25.0
37
39
  Requires-Dist: mcp>=1.0.0
38
40
  Requires-Dist: pydantic>=2.0.0
39
41
  Requires-Dist: python-nmap>=0.7.1
42
+ Requires-Dist: reportlab>=4.0.0
40
43
  Requires-Dist: requests>=2.31.0
41
44
  Requires-Dist: rich>=13.0.0
42
45
  Provides-Extra: ai
@@ -56,9 +59,15 @@ Provides-Extra: gemini
56
59
  Requires-Dist: google-generativeai>=0.7.0; extra == 'gemini'
57
60
  Description-Content-Type: text/markdown
58
61
 
59
- <p align="center">
60
- <img src="docs/assets/logo.svg" alt="offsec-ai" width="520"/>
61
- </p>
62
+ ```
63
+ ██████╗ ███████╗███████╗███████╗███████╗ ██████╗ █████╗ ██╗
64
+ ██╔═══██╗██╔════╝██╔════╝██╔════╝██╔════╝██╔════╝ ██╔══██╗██║
65
+ ██║ ██║█████╗ █████╗ ███████╗█████╗ ██║ █████╗███████║██║
66
+ ██║ ██║██╔══╝ ██╔══╝ ╚════██║██╔══╝ ██║ ╚════╝██╔══██║██║
67
+ ╚██████╔╝██║ ██║ ███████║███████╗╚██████╗ ██║ ██║██║
68
+ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝
69
+ Offensive-Security Toolkit · AI/LLM · MCP · Red-Team
70
+ ```
62
71
 
63
72
  <p align="center">
64
73
  <a href="https://pypi.org/project/offsec-ai/"><img src="https://img.shields.io/pypi/v/offsec-ai" alt="PyPI Version"/></a>
@@ -554,8 +563,23 @@ docker run --rm htunnthuthu/offsec-ai:latest owasp-scan example.com
554
563
  docker run --rm -v $(pwd):/app/output htunnthuthu/offsec-ai:latest \
555
564
  ai-owasp-scan https://api.example.com/v1/chat/completions \
556
565
  --output /app/output/llm-report.json
566
+
567
+ # LLM Judge — openai, anthropic, or gemini key auto-detected; no extra install needed
568
+ docker run --rm \
569
+ -e OPENAI_API_KEY=sk-... \
570
+ htunnthuthu/offsec-ai:latest \
571
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
572
+
573
+ # Custom OpenAI-compatible backend (Ollama, LM Studio, Azure OpenAI…)
574
+ docker run --rm \
575
+ -e OFFSEC_LLM_BASE_URL=http://host.docker.internal:11434/v1 \
576
+ -e OFFSEC_LLM_MODEL=llama3 \
577
+ htunnthuthu/offsec-ai:latest \
578
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
557
579
  ```
558
580
 
581
+ See [docs/DOCKER.md](docs/DOCKER.md) for the full Docker reference including CI/CD integration, Kubernetes jobs, Makefile publish targets, and troubleshooting.
582
+
559
583
  ---
560
584
 
561
585
  ## Configuration
@@ -1,6 +1,12 @@
1
- <p align="center">
2
- <img src="docs/assets/logo.svg" alt="offsec-ai" width="520"/>
3
- </p>
1
+ ```
2
+ ██████╗ ███████╗███████╗███████╗███████╗ ██████╗ █████╗ ██╗
3
+ ██╔═══██╗██╔════╝██╔════╝██╔════╝██╔════╝██╔════╝ ██╔══██╗██║
4
+ ██║ ██║█████╗ █████╗ ███████╗█████╗ ██║ █████╗███████║██║
5
+ ██║ ██║██╔══╝ ██╔══╝ ╚════██║██╔══╝ ██║ ╚════╝██╔══██║██║
6
+ ╚██████╔╝██║ ██║ ███████║███████╗╚██████╗ ██║ ██║██║
7
+ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝
8
+ Offensive-Security Toolkit · AI/LLM · MCP · Red-Team
9
+ ```
4
10
 
5
11
  <p align="center">
6
12
  <a href="https://pypi.org/project/offsec-ai/"><img src="https://img.shields.io/pypi/v/offsec-ai" alt="PyPI Version"/></a>
@@ -496,8 +502,23 @@ docker run --rm htunnthuthu/offsec-ai:latest owasp-scan example.com
496
502
  docker run --rm -v $(pwd):/app/output htunnthuthu/offsec-ai:latest \
497
503
  ai-owasp-scan https://api.example.com/v1/chat/completions \
498
504
  --output /app/output/llm-report.json
505
+
506
+ # LLM Judge — openai, anthropic, or gemini key auto-detected; no extra install needed
507
+ docker run --rm \
508
+ -e OPENAI_API_KEY=sk-... \
509
+ htunnthuthu/offsec-ai:latest \
510
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
511
+
512
+ # Custom OpenAI-compatible backend (Ollama, LM Studio, Azure OpenAI…)
513
+ docker run --rm \
514
+ -e OFFSEC_LLM_BASE_URL=http://host.docker.internal:11434/v1 \
515
+ -e OFFSEC_LLM_MODEL=llama3 \
516
+ htunnthuthu/offsec-ai:latest \
517
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
499
518
  ```
500
519
 
520
+ See [docs/DOCKER.md](docs/DOCKER.md) for the full Docker reference including CI/CD integration, Kubernetes jobs, Makefile publish targets, and troubleshooting.
521
+
501
522
  ---
502
523
 
503
524
  ## Configuration
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## Supported Versions
4
4
 
5
- We provide security updates for the following versions of Simple Port Checker:
5
+ We provide security updates for the following versions of offsec-ai:
6
6
 
7
7
  | Version | Supported |
8
8
  | ------- | ------------------ |
9
- | 0.2.x | :white_check_mark: |
10
- | 0.1.x | :x: |
9
+ | 2.x | :white_check_mark: |
10
+ | 1.x | :x: |
11
11
 
12
12
  ## Reporting a Vulnerability
13
13
 
@@ -15,7 +15,7 @@ We take security vulnerabilities seriously. If you discover a security vulnerabi
15
15
 
16
16
  ### How to Report
17
17
 
18
- 1. **Email**: Send an email to `htunnthuthu.linux@gmail.com` with the subject line "Security Vulnerability in Simple Port Checker"
18
+ 1. **Email**: Send an email to `htunnthuthu.linux@gmail.com` with the subject line "Security Vulnerability in offsec-ai"
19
19
  2. **Include**:
20
20
  - A description of the vulnerability
21
21
  - Steps to reproduce the issue
@@ -38,7 +38,7 @@ We practice responsible disclosure:
38
38
 
39
39
  ## Security Best Practices
40
40
 
41
- When using Simple Port Checker:
41
+ When using offsec-ai:
42
42
 
43
43
  1. **Network Scanning**: Only scan networks you own or have explicit permission to test
44
44
  2. **Rate Limiting**: Use appropriate timeout and concurrency settings to avoid overwhelming target systems
@@ -9,6 +9,7 @@ A comprehensive, lightweight Docker container for network secu## 🔒 Certificat
9
9
  | Tag | Description | Size | Architectures |
10
10
  |-----|-------------|------|---------------|
11
11
  | `latest` | Latest stable release | ~60MB | `linux/amd64`, `linux/arm64` |
12
+ | `v2.0.1` | v2.0.1 — logo fix, docs cleanup | ~60MB | `linux/amd64`, `linux/arm64` |
12
13
  | `v2.0.0` | v2.0.0 — AI/LLM scanner, MCP scanner, Gemini judge | ~60MB | `linux/amd64`, `linux/arm64` |
13
14
 
14
15
  **Recommendation**: Use `latest` for the most recent features, or pin to specific version tags for production deployments.
@@ -259,9 +260,73 @@ spec:
259
260
  - ✅ OCSP and CRL URL extraction for revocation checking
260
261
  - ✅ Certificate fingerprint generation (SHA-1, SHA-256)
261
262
 
262
- ## �🔧 Configuration & Environment
263
+ ## 🤖 AI / LLM Security Usage
264
+
265
+ The image ships with `openai` and `anthropic` pre-installed (`[ai]` extra). Pass an API key at runtime to enable the **LLM Judge** for smarter semantic vulnerability detection.
266
+
267
+ ### AI OWASP Top 10 Scan (rule-based, no key required)
268
+ ```bash
269
+ docker run --rm htunnthuthu/offsec-ai:latest \
270
+ ai-owasp-scan https://api.example.com/v1/chat/completions
271
+ ```
272
+
273
+ ### AI OWASP Top 10 Scan with LLM Judge
263
274
 
264
- ### Environment Variables
275
+ ```bash
276
+ # OpenAI judge
277
+ docker run --rm \
278
+ -e OPENAI_API_KEY=sk-... \
279
+ htunnthuthu/offsec-ai:latest \
280
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
281
+
282
+ # Anthropic judge
283
+ docker run --rm \
284
+ -e ANTHROPIC_API_KEY=sk-ant-... \
285
+ htunnthuthu/offsec-ai:latest \
286
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
287
+
288
+ # Google Gemini judge (no extra package needed)
289
+ docker run --rm \
290
+ -e GEMINI_API_KEY=AIzaSy... \
291
+ htunnthuthu/offsec-ai:latest \
292
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
293
+
294
+ # Custom OpenAI-compatible endpoint (Ollama, LM Studio, Azure OpenAI, etc.)
295
+ docker run --rm \
296
+ -e OFFSEC_LLM_BASE_URL=http://host.docker.internal:11434/v1 \
297
+ -e OFFSEC_LLM_MODEL=llama3 \
298
+ htunnthuthu/offsec-ai:latest \
299
+ ai-owasp-scan https://api.example.com/v1/chat/completions --llm-judge
300
+ ```
301
+
302
+ ### MCP Security Scan
303
+ ```bash
304
+ # Scan an MCP endpoint
305
+ docker run --rm htunnthuthu/offsec-ai:latest \
306
+ mcp-scan https://mcp.example.com/mcp
307
+
308
+ # Active MCP attack (requires authorization flag)
309
+ docker run --rm htunnthuthu/offsec-ai:latest \
310
+ mcp-attack https://mcp.example.com/mcp --i-have-authorization --mode deep
311
+ ```
312
+
313
+ ---
314
+
315
+ ## 🔧 Configuration & Environment
316
+
317
+ ### LLM / AI Judge Environment Variables
318
+
319
+ | Variable | Provider | Description |
320
+ |----------|----------|-------------|
321
+ | `OPENAI_API_KEY` | OpenAI | Enables OpenAI judge (e.g. `gpt-4o-mini`) |
322
+ | `ANTHROPIC_API_KEY` | Anthropic | Enables Anthropic judge (e.g. `claude-3-haiku`) |
323
+ | `GEMINI_API_KEY` | Google | Enables Gemini judge (e.g. `gemini-1.5-flash`) |
324
+ | `OFFSEC_LLM_BASE_URL` | Any OpenAI-compatible | Use a custom/local endpoint as the judge backend |
325
+ | `OFFSEC_LLM_MODEL` | All | Override the default model name |
326
+
327
+ Provider is **auto-detected** from whichever key is set; `OFFSEC_LLM_BASE_URL` takes precedence over `OPENAI_API_KEY`.
328
+
329
+ ### General Environment Variables
265
330
  ```bash
266
331
  # Set timeout for operations
267
332
  docker run --rm -e TIMEOUT=30 htunnthuthu/offsec-ai:latest scan example.com
@@ -293,12 +358,12 @@ docker run --rm -v /host/certs:/app/certs \
293
358
  ## 🔒 Security Features
294
359
 
295
360
  ### Non-Root User
296
- - ✅ Container runs as non-root user `scanner` (UID: 1000)
361
+ - ✅ Container runs as non-root user `appuser` (UID: 1000)
297
362
  - ✅ No privileged access required
298
363
  - ✅ Minimal attack surface
299
364
 
300
365
  ### Minimal Dependencies
301
- - ✅ Based on Alpine Linux for small footprint
366
+ - ✅ Based on Debian slim for minimal footprint
302
367
  - ✅ Only essential packages included
303
368
  - ✅ Regular security updates via automated builds
304
369
 
@@ -310,17 +375,18 @@ docker run --rm -v /host/certs:/app/certs \
310
375
  ## 🏷️ Image Specifications
311
376
 
312
377
  ### Base Image
313
- - **OS**: Alpine Linux (latest stable)
378
+ - **OS**: Debian GNU/Linux 12 Bookworm slim (`python:3.12-slim-bookworm`)
314
379
  - **Python**: 3.12+
315
380
  - **Architecture**: Multi-arch (AMD64, ARM64)
316
- - **User**: Non-root (`scanner:scanner`)
381
+ - **User**: Non-root (`appuser:appuser`, UID/GID 1000)
317
382
 
318
383
  ### Installed Tools
319
- - ✅ Simple Port Checker (latest version)
384
+ - ✅ `offsec-ai` (latest version)
320
385
  - ✅ Python runtime and required dependencies
386
+ - ✅ `openai` & `anthropic` packages — bundled via `[ai]` extra; LLM judge activates automatically when you pass an API key env var
321
387
  - ✅ SSL/TLS libraries for certificate handling
322
388
  - ✅ DNS resolution utilities
323
- - ✅ OpenSSL for certificate chain extraction
389
+ - ✅ `nmap` for port scanning
324
390
  - ✅ Cryptography libraries for certificate analysis
325
391
 
326
392
  ### Performance
@@ -429,7 +495,42 @@ docker run --rm --memory=512m htunnthuthu/offsec-ai:latest scan example.com
429
495
  docker run --rm --cpus=2 htunnthuthu/offsec-ai:latest full-scan example.com
430
496
  ```
431
497
 
432
- ## 🔗 Related Links
498
+ ## �️ Building & Publishing Locally
499
+
500
+ The `Makefile` provides convenience targets for building and pushing to Docker Hub.
501
+
502
+ ```bash
503
+ # Build the image locally
504
+ make docker-build
505
+
506
+ # Build without cache
507
+ make docker-build-no-cache
508
+
509
+ # Build multi-arch (linux/amd64 + linux/arm64) — requires docker buildx
510
+ make docker-build-multi
511
+
512
+ # Push to Docker Hub (builds first, then tags + pushes :version and :latest)
513
+ make docker-push # uses DOCKER_USERNAME=htunn by default
514
+ make docker-push DOCKER_USERNAME=youruser # override username
515
+
516
+ # Full release in one command
517
+ make docker-release # equivalent to docker-build + docker-push
518
+
519
+ # Test the local image
520
+ make docker-test
521
+
522
+ # Scan image for vulnerabilities (requires trivy)
523
+ make docker-scan
524
+
525
+ # Clean up local Docker artifacts
526
+ make docker-clean
527
+ ```
528
+
529
+ The `DOCKER_VERSION` is read automatically from `pyproject.toml`, so the published tags match the package version exactly.
530
+
531
+ ---
532
+
533
+ ## �🔗 Related Links
433
534
 
434
535
  - **GitHub Repository**: [Htunn/offsec-ai](https://github.com/Htunn/offsec-ai)
435
536
  - **PyPI Package**: [offsec-ai](https://pypi.org/project/offsec-ai/)
@@ -49,7 +49,7 @@
49
49
  <!-- Version badge -->
50
50
  <rect x="62" y="94" width="52" height="16" rx="3" fill="#cc000033" stroke="#cc000066" stroke-width="0.8"/>
51
51
  <text x="88" y="106" font-family="'Courier New', Courier, monospace" font-size="9"
52
- fill="#ff6666" text-anchor="middle">v2.0.0</text>
52
+ fill="#ff6666" text-anchor="middle">v2.0.1</text>
53
53
 
54
54
  <!-- Right decorative dots (terminal-like) -->
55
55
  <circle cx="470" cy="26" r="5" fill="#ff4444" opacity="0.9"/>
@@ -28,9 +28,8 @@ offsec-ai ai-owasp-scan https://api.example.com/v1/chat/completions \
28
28
  offsec-ai mcp-scan https://mcp.example.com/mcp
29
29
  offsec-ai mcp-scan https://mcp.example.com/mcp --output report.json
30
30
 
31
- # MCP attacker (requires --authorized flag)
32
- offsec-ai mcp-attack https://mcp.example.com/mcp --authorized \
33
- --auth-token "$TOKEN"
31
+ # MCP attacker (requires --i-have-authorization flag)
32
+ offsec-ai mcp-attack https://mcp.example.com/mcp --i-have-authorization
34
33
  ```
35
34
 
36
35
  ### Python API
@@ -167,6 +166,7 @@ offsec-ai scan example.com --verbose
167
166
  ## Examples
168
167
 
169
168
  See the `examples/` directory for complete usage examples:
170
- - `usage_examples.py` - Comprehensive examples
171
- - `batch_scanning.py` - Batch scanning multiple targets
172
- - `custom_config.py` - Custom configuration examples
169
+ - `usage_examples.py` Core infrastructure scanning examples
170
+ - `comprehensive_examples.py` All features with detailed output
171
+ - `mtls_examples.py` mTLS testing and certificate generation
172
+ - `owasp_scan_examples.py` — OWASP Top 10 scanning with PDF/CSV export
@@ -4,16 +4,18 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "offsec-ai"
7
- version = "2.0.0"
7
+ version = "2.0.2"
8
8
  description = "Offensive-security toolkit: port scanning, L7/WAF detection, mTLS, certificate analysis, OWASP Top 10, AI/LLM OWASP Top 10 black-box probing, and MCP endpoint security scanning"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
11
  license = {text = "MIT"}
12
12
  authors = [
13
- {name = "htunn", email = "htunnthuthu.linux@gmail.com"}
13
+ {name = "Htunn"},
14
+ {email = "htunnthuthu.linux@gmail.com"}
14
15
  ]
15
16
  maintainers = [
16
- {name = "htunn", email = "htunnthuthu.linux@gmail.com"}
17
+ {name = "Htunn"},
18
+ {email = "htunnthuthu.linux@gmail.com"}
17
19
  ]
18
20
  keywords = ["firewall", "port-scanner", "l7-protection", "waf", "network", "security", "ssl", "tls", "certificate", "certificate-analysis", "pki", "offensive-security", "red-team", "pentest", "ai", "llm", "mcp", "owasp", "ai-security", "model-context-protocol"]
19
21
  classifiers = [
@@ -46,6 +48,7 @@ dependencies = [
46
48
  "cryptography>=41.0.0",
47
49
  "mcp>=1.0.0",
48
50
  "httpx>=0.25.0",
51
+ "reportlab>=4.0.0",
49
52
  ]
50
53
 
51
54
  [project.optional-dependencies]
@@ -16,7 +16,7 @@ Capabilities:
16
16
  - Rich CLI interface with progress bars
17
17
  """
18
18
 
19
- __version__ = "2.0.0"
19
+ __version__ = "2.0.2"
20
20
  __author__ = "htunn"
21
21
  __email__ = "htunnthuthu.linux@gmail.com"
22
22
  __license__ = "MIT"
@@ -98,7 +98,7 @@ class LLMOwaspScanner:
98
98
  async with httpx.AsyncClient(
99
99
  headers={
100
100
  "Content-Type": "application/json",
101
- "User-Agent": "offsec-ai/2.0.0",
101
+ "User-Agent": "offsec-ai/2.0.1",
102
102
  **self.headers,
103
103
  },
104
104
  timeout=self.timeout,
@@ -91,7 +91,7 @@ class HybridIdentityChecker:
91
91
  timeout: Request timeout in seconds
92
92
  """
93
93
  self.timeout = timeout
94
- self.user_agent = "SimplePortChecker/1.0 (Hybrid Identity Scanner)"
94
+ self.user_agent = "offsec-ai/2.0 (Hybrid Identity Scanner)"
95
95
 
96
96
  async def check(self, fqdn: str) -> HybridIdentityResult:
97
97
  """
@@ -55,7 +55,7 @@ class L7Detector:
55
55
  user_agent: Custom User-Agent string
56
56
  """
57
57
  self.timeout = timeout
58
- self.user_agent = user_agent or "SimplePortChecker/1.0 (Security Scanner)"
58
+ self.user_agent = user_agent or "offsec-ai/2.0 (Security Scanner)"
59
59
  self.signatures = L7_SIGNATURES
60
60
 
61
61
  async def detect(self, host: str, port: int = None, path: str = "/", trace_dns: bool = False) -> L7Result:
@@ -169,7 +169,7 @@ class MCPAttacker:
169
169
  test_headers = {
170
170
  "Content-Type": "application/json",
171
171
  "Accept": "application/json, text/event-stream",
172
- "User-Agent": "offsec-ai/2.0.0",
172
+ "User-Agent": "offsec-ai/2.0.1",
173
173
  **probe.get("headers", {}),
174
174
  }
175
175
  triggered = False
@@ -233,7 +233,7 @@ class MCPAttacker:
233
233
  async with httpx.AsyncClient(
234
234
  headers={"Content-Type": "application/json",
235
235
  "Accept": "application/json, text/event-stream",
236
- "User-Agent": "offsec-ai/2.0.0", **headers},
236
+ "User-Agent": "offsec-ai/2.0.1", **headers},
237
237
  timeout=timeout,
238
238
  ) as client:
239
239
  resp = await client.post(target, json=payload)
@@ -295,7 +295,7 @@ class MCPAttacker:
295
295
  async with httpx.AsyncClient(
296
296
  headers={"Content-Type": "application/json",
297
297
  "Accept": "application/json, text/event-stream",
298
- "User-Agent": "offsec-ai/2.0.0", **headers},
298
+ "User-Agent": "offsec-ai/2.0.1", **headers},
299
299
  timeout=timeout,
300
300
  ) as client:
301
301
  resp = await client.post(target, json=payload)
@@ -356,7 +356,7 @@ class MCPAttacker:
356
356
  async with httpx.AsyncClient(
357
357
  headers={"Content-Type": "application/json",
358
358
  "Accept": "application/json, text/event-stream",
359
- "User-Agent": "offsec-ai/2.0.0", **headers},
359
+ "User-Agent": "offsec-ai/2.0.1", **headers},
360
360
  timeout=timeout,
361
361
  ) as client:
362
362
  resp = await client.post(target, json=payload)
@@ -97,7 +97,7 @@ class MCPScanner:
97
97
  headers={
98
98
  "Content-Type": "application/json",
99
99
  "Accept": "application/json, text/event-stream",
100
- "User-Agent": "offsec-ai/2.0.0",
100
+ "User-Agent": "offsec-ai/2.0.1",
101
101
  **self.headers,
102
102
  },
103
103
  timeout=self.timeout,
@@ -189,7 +189,7 @@ class MCPScanner:
189
189
 
190
190
  # Try without any auth header
191
191
  no_auth_client = httpx.AsyncClient(
192
- headers={"Content-Type": "application/json", "Accept": "application/json, text/event-stream", "User-Agent": "offsec-ai/2.0.0"},
192
+ headers={"Content-Type": "application/json", "Accept": "application/json, text/event-stream", "User-Agent": "offsec-ai/2.0.1"},
193
193
  timeout=self.timeout,
194
194
  )
195
195
  async with no_auth_client:
@@ -0,0 +1,102 @@
1
+ """Tests for mTLS models and CLI commands."""
2
+
3
+ from datetime import datetime
4
+
5
+
6
+ def test_imports():
7
+ """All mTLS modules import without error."""
8
+ from offsec_ai.models.mtls_result import BatchMTLSResult, CertificateInfo, MTLSResult # noqa: F401
9
+ from offsec_ai.core.mtls_checker import MTLSChecker # noqa: F401
10
+
11
+
12
+ def test_certificate_info_model():
13
+ """CertificateInfo model fields are created correctly."""
14
+ from offsec_ai.models.mtls_result import CertificateInfo
15
+
16
+ cert = CertificateInfo(
17
+ subject="CN=test.example.com",
18
+ issuer="CN=Test CA",
19
+ version=3,
20
+ serial_number="12345",
21
+ not_valid_before="2024-01-01T00:00:00",
22
+ not_valid_after="2025-01-01T00:00:00",
23
+ signature_algorithm="sha256WithRSAEncryption",
24
+ key_algorithm="RSAPublicKey",
25
+ key_size=2048,
26
+ san_dns_names=["test.example.com", "*.example.com"],
27
+ san_ip_addresses=["192.168.1.1"],
28
+ is_ca=False,
29
+ is_self_signed=False,
30
+ fingerprint_sha256="abcd1234...",
31
+ )
32
+ assert cert.subject == "CN=test.example.com"
33
+ assert cert.key_size == 2048
34
+ assert "test.example.com" in cert.san_dns_names
35
+ assert cert.is_ca is False
36
+
37
+
38
+ def test_mtls_result_model():
39
+ """MTLSResult is created, fields are accessible, and serializes to JSON."""
40
+ from offsec_ai.models.mtls_result import CertificateInfo, MTLSResult
41
+
42
+ cert = CertificateInfo(
43
+ subject="CN=test.example.com",
44
+ issuer="CN=Test CA",
45
+ version=3,
46
+ serial_number="12345",
47
+ not_valid_before="2024-01-01T00:00:00",
48
+ not_valid_after="2025-01-01T00:00:00",
49
+ signature_algorithm="sha256WithRSAEncryption",
50
+ key_algorithm="RSAPublicKey",
51
+ key_size=2048,
52
+ san_dns_names=["test.example.com"],
53
+ san_ip_addresses=[],
54
+ is_ca=False,
55
+ is_self_signed=False,
56
+ fingerprint_sha256="abcd1234...",
57
+ )
58
+ result = MTLSResult(
59
+ target="test.example.com",
60
+ port=443,
61
+ supports_mtls=True,
62
+ requires_client_cert=False,
63
+ server_cert_info=cert,
64
+ client_cert_requested=True,
65
+ handshake_successful=False,
66
+ error_message=None,
67
+ cipher_suite="TLS_AES_256_GCM_SHA384",
68
+ tls_version="TLSv1.3",
69
+ verification_mode="default",
70
+ ca_bundle_path="/etc/ssl/certs/ca-certificates.crt",
71
+ timestamp=datetime.now().isoformat(),
72
+ )
73
+ assert result.target == "test.example.com"
74
+ assert result.port == 443
75
+ assert result.supports_mtls is True
76
+ assert result.server_cert_info.key_size == 2048
77
+
78
+ json_str = result.model_dump_json()
79
+ assert "test.example.com" in json_str
80
+ assert "TLSv1.3" in json_str
81
+
82
+
83
+ def test_cli_mtls_commands_exist():
84
+ """mTLS CLI commands are registered and return help text."""
85
+ from click.testing import CliRunner
86
+
87
+ from offsec_ai.cli import main
88
+
89
+ runner = CliRunner()
90
+
91
+ result = runner.invoke(main, ["--help"])
92
+ assert result.exit_code == 0
93
+ assert "mtls-check" in result.output
94
+
95
+ result = runner.invoke(main, ["mtls-check", "--help"])
96
+ assert result.exit_code == 0
97
+
98
+ result = runner.invoke(main, ["mtls-gen-cert", "--help"])
99
+ assert result.exit_code == 0
100
+
101
+ result = runner.invoke(main, ["mtls-validate-cert", "--help"])
102
+ assert result.exit_code == 0