@orionscanner/cli 0.1.0

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 (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +248 -0
  3. package/assets/logo.png +0 -0
  4. package/bin/orion.js +48 -0
  5. package/docs/API_REFERENCE.md +211 -0
  6. package/docs/ARCHITECTURE.md +183 -0
  7. package/docs/CHANGELOG.md +112 -0
  8. package/docs/CONTRIBUTING.md +157 -0
  9. package/docs/ENGINE_CATALOG.md +87 -0
  10. package/docs/GETTING_STARTED.md +226 -0
  11. package/package.json +48 -0
  12. package/pyproject.toml +16 -0
  13. package/src/orion/__init__.py +0 -0
  14. package/src/orion/__pycache__/__init__.cpython-313.pyc +0 -0
  15. package/src/orion/engine/__init__.py +17 -0
  16. package/src/orion/engine/__pycache__/__init__.cpython-313.pyc +0 -0
  17. package/src/orion/engine/__pycache__/config.cpython-313.pyc +0 -0
  18. package/src/orion/engine/__pycache__/core.cpython-313.pyc +0 -0
  19. package/src/orion/engine/__pycache__/ir.cpython-313.pyc +0 -0
  20. package/src/orion/engine/__pycache__/languages.cpython-313.pyc +0 -0
  21. package/src/orion/engine/__pycache__/registry.cpython-313.pyc +0 -0
  22. package/src/orion/engine/__pycache__/results.cpython-313.pyc +0 -0
  23. package/src/orion/engine/__pycache__/runner.cpython-313.pyc +0 -0
  24. package/src/orion/engine/api_security/__pycache__/engine.cpython-313.pyc +0 -0
  25. package/src/orion/engine/api_security/engine.py +125 -0
  26. package/src/orion/engine/architecture/__pycache__/engine.cpython-313.pyc +0 -0
  27. package/src/orion/engine/architecture/engine.py +463 -0
  28. package/src/orion/engine/authorization/__pycache__/engine.cpython-313.pyc +0 -0
  29. package/src/orion/engine/authorization/engine.py +337 -0
  30. package/src/orion/engine/callgraph/__pycache__/engine.cpython-313.pyc +0 -0
  31. package/src/orion/engine/callgraph/engine.py +236 -0
  32. package/src/orion/engine/cfg/__pycache__/engine.cpython-313.pyc +0 -0
  33. package/src/orion/engine/cfg/engine.py +509 -0
  34. package/src/orion/engine/chaos/__pycache__/engine.cpython-313.pyc +0 -0
  35. package/src/orion/engine/chaos/engine.py +268 -0
  36. package/src/orion/engine/chaos_config/__pycache__/engine.cpython-313.pyc +0 -0
  37. package/src/orion/engine/chaos_config/engine.py +322 -0
  38. package/src/orion/engine/complexity/__pycache__/engine.cpython-313.pyc +0 -0
  39. package/src/orion/engine/complexity/engine.py +144 -0
  40. package/src/orion/engine/compliance/__pycache__/engine.cpython-313.pyc +0 -0
  41. package/src/orion/engine/compliance/engine.py +325 -0
  42. package/src/orion/engine/config.py +41 -0
  43. package/src/orion/engine/config_engine/__pycache__/engine.cpython-313.pyc +0 -0
  44. package/src/orion/engine/config_engine/engine.py +364 -0
  45. package/src/orion/engine/config_validation/__pycache__/engine.cpython-313.pyc +0 -0
  46. package/src/orion/engine/config_validation/engine.py +313 -0
  47. package/src/orion/engine/container/__pycache__/engine.cpython-313.pyc +0 -0
  48. package/src/orion/engine/container/engine.py +546 -0
  49. package/src/orion/engine/contract_probe/__pycache__/engine.cpython-313.pyc +0 -0
  50. package/src/orion/engine/contract_probe/engine.py +316 -0
  51. package/src/orion/engine/core.py +75 -0
  52. package/src/orion/engine/crypto_guard/__pycache__/engine.cpython-313.pyc +0 -0
  53. package/src/orion/engine/crypto_guard/engine.py +134 -0
  54. package/src/orion/engine/data_residency/__pycache__/engine.cpython-313.pyc +0 -0
  55. package/src/orion/engine/data_residency/engine.py +238 -0
  56. package/src/orion/engine/dataflow/__pycache__/engine.cpython-313.pyc +0 -0
  57. package/src/orion/engine/dataflow/engine.py +398 -0
  58. package/src/orion/engine/dead_import/__pycache__/engine.cpython-313.pyc +0 -0
  59. package/src/orion/engine/dead_import/engine.py +293 -0
  60. package/src/orion/engine/deps/__pycache__/engine.cpython-313.pyc +0 -0
  61. package/src/orion/engine/deps/engine.py +244 -0
  62. package/src/orion/engine/dispatcher.py +350 -0
  63. package/src/orion/engine/docs/AUDIT_PROMPT.md +1248 -0
  64. package/src/orion/engine/duplication/__pycache__/engine.cpython-313.pyc +0 -0
  65. package/src/orion/engine/duplication/engine.py +120 -0
  66. package/src/orion/engine/error_handling/__pycache__/engine.cpython-313.pyc +0 -0
  67. package/src/orion/engine/error_handling/engine.py +256 -0
  68. package/src/orion/engine/fp_learn/__pycache__/engine.cpython-313.pyc +0 -0
  69. package/src/orion/engine/fp_learn/engine.py +248 -0
  70. package/src/orion/engine/hunter/__pycache__/engine.cpython-313.pyc +0 -0
  71. package/src/orion/engine/hunter/engine.py +324 -0
  72. package/src/orion/engine/iac_security/__pycache__/engine.cpython-313.pyc +0 -0
  73. package/src/orion/engine/iac_security/engine.py +218 -0
  74. package/src/orion/engine/ir.py +22 -0
  75. package/src/orion/engine/languages.py +454 -0
  76. package/src/orion/engine/license/__pycache__/engine.cpython-313.pyc +0 -0
  77. package/src/orion/engine/license/engine.py +172 -0
  78. package/src/orion/engine/lint/__pycache__/engine.cpython-313.pyc +0 -0
  79. package/src/orion/engine/lint/engine.py +558 -0
  80. package/src/orion/engine/llm_security/__pycache__/engine.cpython-313.pyc +0 -0
  81. package/src/orion/engine/llm_security/engine.py +125 -0
  82. package/src/orion/engine/logging_c/__pycache__/engine.cpython-313.pyc +0 -0
  83. package/src/orion/engine/logging_c/engine.py +164 -0
  84. package/src/orion/engine/noise/__pycache__/engine.cpython-313.pyc +0 -0
  85. package/src/orion/engine/noise/engine.py +140 -0
  86. package/src/orion/engine/orphan/__pycache__/engine.cpython-313.pyc +0 -0
  87. package/src/orion/engine/orphan/engine.py +244 -0
  88. package/src/orion/engine/perf_guard/__pycache__/engine.cpython-313.pyc +0 -0
  89. package/src/orion/engine/perf_guard/engine.py +345 -0
  90. package/src/orion/engine/prompt_security/__pycache__/engine.cpython-313.pyc +0 -0
  91. package/src/orion/engine/prompt_security/detectors/__init__.py +4 -0
  92. package/src/orion/engine/prompt_security/engine.py +170 -0
  93. package/src/orion/engine/provenance/__pycache__/engine.cpython-313.pyc +0 -0
  94. package/src/orion/engine/provenance/engine.py +242 -0
  95. package/src/orion/engine/registry.py +55 -0
  96. package/src/orion/engine/regression/__pycache__/engine.cpython-313.pyc +0 -0
  97. package/src/orion/engine/regression/engine.py +213 -0
  98. package/src/orion/engine/results.py +21 -0
  99. package/src/orion/engine/runner.py +1310 -0
  100. package/src/orion/engine/sandbox_escape/__pycache__/engine.cpython-313.pyc +0 -0
  101. package/src/orion/engine/sandbox_escape/engine.py +284 -0
  102. package/src/orion/engine/sast/__pycache__/engine.cpython-313.pyc +0 -0
  103. package/src/orion/engine/sast/engine.py +217 -0
  104. package/src/orion/engine/sast/patterns/__init__.py +513 -0
  105. package/src/orion/engine/sast/patterns/__pycache__/__init__.cpython-313.pyc +0 -0
  106. package/src/orion/engine/secrets/__pycache__/engine.cpython-313.pyc +0 -0
  107. package/src/orion/engine/secrets/engine.py +77 -0
  108. package/src/orion/engine/secrets/patterns/__init__.py +74 -0
  109. package/src/orion/engine/secrets/patterns/__pycache__/__init__.cpython-313.pyc +0 -0
  110. package/src/orion/engine/sensitive_data/__pycache__/engine.cpython-313.pyc +0 -0
  111. package/src/orion/engine/sensitive_data/engine.py +143 -0
  112. package/src/orion/engine/state/__pycache__/engine.cpython-313.pyc +0 -0
  113. package/src/orion/engine/state/engine.py +218 -0
  114. package/src/orion/engine/supply_chain_sbom/__pycache__/engine.cpython-313.pyc +0 -0
  115. package/src/orion/engine/supply_chain_sbom/engine.py +290 -0
  116. package/src/orion/engine/symbol/__pycache__/engine.cpython-313.pyc +0 -0
  117. package/src/orion/engine/symbol/engine.py +463 -0
  118. package/src/orion/engine/taint/__pycache__/engine.cpython-313.pyc +0 -0
  119. package/src/orion/engine/taint/engine.py +464 -0
  120. package/src/orion/engine/test_coverage/__pycache__/engine.cpython-313.pyc +0 -0
  121. package/src/orion/engine/test_coverage/engine.py +445 -0
  122. package/src/orion/engine/threat_model/__pycache__/engine.cpython-313.pyc +0 -0
  123. package/src/orion/engine/threat_model/engine.py +126 -0
  124. package/src/orion/engine/wiring_trace/__pycache__/engine.cpython-313.pyc +0 -0
  125. package/src/orion/engine/wiring_trace/engine.py +200 -0
  126. package/src/orion_engine.egg-info/PKG-INFO +7 -0
  127. package/src/orion_engine.egg-info/SOURCES.txt +65 -0
  128. package/src/orion_engine.egg-info/dependency_links.txt +1 -0
  129. package/src/orion_engine.egg-info/entry_points.txt +2 -0
  130. package/src/orion_engine.egg-info/top_level.txt +1 -0
@@ -0,0 +1,226 @@
1
+ # Getting Started
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ # From source
7
+ git clone https://github.com/chandrahotha/OrionEngine
8
+ cd OrionEngine
9
+ pip install -e .
10
+
11
+ # Or from PyPI (when published)
12
+ pip install orion-engine
13
+ ```
14
+
15
+ Requires Python 3.10+
16
+
17
+ ## Quick Start
18
+
19
+ ### 1. Interactive Menu
20
+ ```bash
21
+ orion
22
+ ```
23
+ Opens interactive menu with 9 options:
24
+ 1. **Quick Scan** — Fast security check of current project
25
+ 2. **Full Security Audit** — Complete analysis with all 38 engines
26
+ 3. **Vulnerability Scan** — SAST, Secrets, Dependencies, Injection
27
+ 4. **Code Quality Review** — Complexity, Duplication, Standards, Tests
28
+ 5. **Architecture Analysis** — Dependencies, Layers, Coupling, Design
29
+ 6. **Supply Chain Security** — SBOM, Provenance, Compliance, Containers
30
+ 7. **View Reports** — Browse previous scan reports
31
+ 8. **Settings** — Configure limits, exclusions, network
32
+ 9. **System Status** — Engine health and availability
33
+
34
+ ### 2. Direct Command Line
35
+ ```bash
36
+ # Scan current directory
37
+ orion .
38
+
39
+ # Scan specific path
40
+ orion ./my_project
41
+ orion path/to/file.py
42
+
43
+ # Security-focused scan (SAST, Secrets, Deps, Taint, Auth)
44
+ orion . --security
45
+
46
+ # Quality-focused scan (Complexity, Lint, Duplication, Tests)
47
+ orion . --quality
48
+
49
+ # Architecture scan (Callgraph, CFG, Symbols, Layers)
50
+ orion . --arch
51
+
52
+ # Custom config
53
+ orion . --config-json '{"resource_limits":{"max_cpu_seconds":30}}'
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ ### EngineConfig
59
+ ```python
60
+ from orion.engine import EngineConfig, ResourceLimits, NetworkPolicy
61
+
62
+ config = EngineConfig(
63
+ toggles={
64
+ "exclude": ["tests/", "vendor/", "migrations/", "*.min.js"],
65
+ "only_engines": ["sast", "secrets", "deps"],
66
+ "severity_threshold": "medium",
67
+ },
68
+ resource_limits=ResourceLimits(
69
+ max_cpu_seconds=120,
70
+ max_memory_mb=1024,
71
+ max_file_size_mb=10,
72
+ max_files=50000
73
+ ),
74
+ network_policy=NetworkPolicy(
75
+ allow_outbound=False,
76
+ allowed_hosts=[]
77
+ )
78
+ )
79
+ ```
80
+
81
+ ### ResourceLimits
82
+ | Parameter | Default | Description |
83
+ |-----------|---------|-------------|
84
+ | `max_cpu_seconds` | 60 | Timeout per engine |
85
+ | `max_memory_mb` | 512 | Memory limit per engine |
86
+ | `max_file_size_mb` | 10 | Skip files larger than this |
87
+ | `max_files` | 50000 | Max files to scan |
88
+
89
+ ### NetworkPolicy
90
+ ```python
91
+ NetworkPolicy(
92
+ allow_outbound=False, # Block all external calls (default)
93
+ allowed_hosts=[] # Allowlist if outbound enabled
94
+ )
95
+ ```
96
+
97
+ ## Reports
98
+
99
+ Reports generated in `ORION SCANNER REPORTS/`:
100
+ - **HTML** — Dark theme, sidebar navigation, expandable findings, score/grade (A-F)
101
+ - **JSON** — Machine-readable for CI/CD integration
102
+ - **TXT** — Human-readable summary
103
+
104
+ ```bash
105
+ # Open latest HTML report (Windows)
106
+ start "ORION SCANNER REPORTS\*.html"
107
+
108
+ # Open latest HTML report (Linux/macOS)
109
+ xdg-open "ORION SCANNER REPORTS"/*.html
110
+ ```
111
+
112
+ ## Programmatic Usage
113
+
114
+ ```python
115
+ import asyncio
116
+ from orion.engine import OrionEngine, EngineConfig, ResourceLimits
117
+ from orion.engine.ir import OrionIR
118
+ from pathlib import Path
119
+
120
+ async def scan_project(project_path: str):
121
+ engine = OrionEngine()
122
+
123
+ # Collect files
124
+ files = list(Path(project_path).rglob("*.py"))
125
+ irs = []
126
+ for f in files:
127
+ content = f.read_bytes()
128
+ irs.append(OrionIR(
129
+ content=content,
130
+ metadata={"path": str(f.relative_to(project_path)), "language": "python"}
131
+ ))
132
+
133
+ config = EngineConfig(
134
+ resource_limits=ResourceLimits(max_cpu_seconds=120, max_memory_mb=1024)
135
+ )
136
+
137
+ result = await engine.run(irs, config)
138
+
139
+ print(f"Scanned {len(files)} files")
140
+ print(f"Found {len(result.findings)} issues")
141
+ print(f"Grade: {calculate_grade(result.findings)}")
142
+
143
+ for f in result.findings:
144
+ if f.severity in ("critical", "high"):
145
+ print(f" [{f.severity.upper()}] {f.title} @ {f.location}")
146
+
147
+ asyncio.run(scan_project("."))
148
+ ```
149
+
150
+ ## Exit Codes
151
+ - `0` — No critical/high findings
152
+ - `1` — Critical or high severity findings found
153
+
154
+ ## Multi-Language Support
155
+
156
+ Orion automatically detects language from file extension:
157
+
158
+ | Extension | Language | SAST Support |
159
+ |-----------|----------|--------------|
160
+ | `.py` | Python | AST + Regex |
161
+ | `.js`, `.jsx`, `.ts`, `.tsx` | JavaScript/TypeScript | Regex |
162
+ | `.java` | Java | Regex |
163
+ | `.go` | Go | Regex |
164
+ | `.rs` | Rust | Regex |
165
+ | `.php` | PHP | Regex |
166
+ | `.rb` | Ruby | Regex |
167
+ | `.cs` | C# | Regex |
168
+ | `.cpp`, `.cc`, `.c`, `.h` | C/C++ | Regex |
169
+ | `.html`, `.htm` | HTML | Regex |
170
+ | `.yml`, `.yaml`, `.json`, `.toml` | Config | Regex |
171
+ | `Dockerfile` | Dockerfile | Regex |
172
+
173
+ ## Excluding Files/Directories
174
+
175
+ ```python
176
+ config = EngineConfig(
177
+ toggles={
178
+ "exclude": [
179
+ "tests/", "test/", "tests/**",
180
+ "vendor/", "node_modules/",
181
+ "migrations/", "dist/", "build/",
182
+ "*.min.js", "*.min.css",
183
+ "generated/", "*.pb.go"
184
+ ]
185
+ }
186
+ )
187
+ ```
188
+
189
+ ## CI/CD Integration
190
+
191
+ ```yaml
192
+ # GitHub Actions example
193
+ - name: Orion Security Scan
194
+ run: |
195
+ pip install orion-engine
196
+ orion . --security
197
+ ```
198
+
199
+ ## False Positive Feedback
200
+
201
+ Create `.orion-feedback.json` in project root:
202
+ ```json
203
+ {
204
+ "findings": [
205
+ {
206
+ "engine": "sast",
207
+ "location": "app.py:42",
208
+ "title": "SQL Injection",
209
+ "feedback": "false_positive",
210
+ "reason": "Parameterized query used"
211
+ }
212
+ ]
213
+ }
214
+ ```
215
+
216
+ Orion learns from feedback and reduces confidence on similar patterns.
217
+
218
+ ## Troubleshooting
219
+
220
+ | Issue | Solution |
221
+ |-------|----------|
222
+ | `ModuleNotFoundError: orion` | Run `pip install -e .` from project root |
223
+ | Scan hangs | Reduce `max_cpu_seconds` in ResourceLimits |
224
+ | Too many findings | Increase `severity_threshold` or add exclude patterns |
225
+ | No findings | Check language detection, add file extensions |
226
+ | Memory error | Reduce `max_memory_mb` or `max_files` |
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@orionscanner/cli",
3
+ "version": "0.1.0",
4
+ "description": "Orion Security Suite - Proprietary In-House Code Intelligence, SAST & Architecture Auditing Platform",
5
+ "main": "bin/orion.js",
6
+ "bin": {
7
+ "orion": "./bin/orion.js",
8
+ "orion-engine": "./bin/orion.js",
9
+ "orion-cli": "./bin/orion.js"
10
+ },
11
+ "scripts": {
12
+ "start": "node ./bin/orion.js",
13
+ "orion": "node ./bin/orion.js"
14
+ },
15
+ "keywords": [
16
+ "orion",
17
+ "security",
18
+ "sast",
19
+ "code-audit",
20
+ "static-analysis",
21
+ "taint-analysis",
22
+ "code-quality",
23
+ "threat-modeling",
24
+ "privacy-shield",
25
+ "architecture"
26
+ ],
27
+ "author": "Chandra Hotha",
28
+ "license": "UNLICENSED",
29
+ "engines": {
30
+ "node": ">=16.0.0"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/chandrahotha/OrionEngine.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/chandrahotha/OrionEngine/issues"
38
+ },
39
+ "homepage": "https://github.com/chandrahotha/OrionEngine#readme",
40
+ "files": [
41
+ "bin/",
42
+ "src/",
43
+ "assets/",
44
+ "docs/",
45
+ "README.md",
46
+ "pyproject.toml"
47
+ ]
48
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "orion-engine"
7
+ version = "0.1.0"
8
+ description = "Orion Security Suite - Proprietary In-House Code Intelligence & Security Audit Platform"
9
+ requires-python = ">=3.10"
10
+ dependencies = []
11
+
12
+ [project.scripts]
13
+ orion = "orion.engine.runner:main"
14
+
15
+ [tool.setuptools.packages.find]
16
+ where = ["src"]
File without changes
@@ -0,0 +1,17 @@
1
+ from orion.engine.config import EngineConfig, NetworkPolicy, ResourceLimits
2
+ from orion.engine.results import EngineResult, Finding
3
+ from orion.engine.ir import OrionIR
4
+ from orion.engine.registry import EngineRegistry
5
+ from orion.engine.core import OrionEngine
6
+
7
+ __version__ = "1.0.0"
8
+ __all__ = [
9
+ "OrionEngine",
10
+ "EngineConfig",
11
+ "NetworkPolicy",
12
+ "ResourceLimits",
13
+ "EngineResult",
14
+ "Finding",
15
+ "OrionIR",
16
+ "EngineRegistry",
17
+ ]
@@ -0,0 +1,125 @@
1
+ """REST & Microservice API Security Engine.
2
+
3
+ 100% Custom In-House Developed Engine for Orion Engine Platform (OWASP API Security Top 10).
4
+ Detects BOLA/IDOR patterns, mass assignment risks, unvalidated redirects, and exposed debug endpoints.
5
+ """
6
+ import re
7
+ from pathlib import Path
8
+ from typing import List, Dict, Any
9
+
10
+ from orion.engine.config import EngineConfig, ResourceLimits
11
+ from orion.engine.ir import OrionIR
12
+ from orion.engine.results import EngineResult, Finding
13
+
14
+
15
+ API_RULES = [
16
+ {
17
+ "id": "API-001",
18
+ "pattern": r"(?i)@(app|router|api)\.(get|post|put|delete|patch)\s*\([^)]*[\"']/api/[^\"']*\{?(user_id|account_id|org_id|id)\}?[^\"']*[\"']\)\s*\n\s*(?:async\s+)?def\s+[a-zA-Z0-9_]+\s*\([^)]*\):\s*\n(?!\s*.*(?:verify_owner|check_permission|current_user|authorize))",
19
+ "title": "Missing object-level authorization check on ID-parameterized endpoint (API1: BOLA / IDOR)",
20
+ "description": "Endpoint operates directly on user-provided resource identifier without verifying caller ownership",
21
+ "severity": "high",
22
+ "cwe": "CWE-639",
23
+ "confidence": 0.8,
24
+ },
25
+ {
26
+ "id": "API-002",
27
+ "pattern": r"(?i)\b(Model\.objects\.create\s*\(\s*\*\*req\.(body|data|POST)|db\.session\.add\s*\(\s*User\s*\(\s*\*\*data\)|update\s*\(\s*\*\*request\.json)\b",
28
+ "title": "Mass assignment vulnerability on user input model mapping (API6: Mass Assignment)",
29
+ "description": "Directly unpacking untrusted request payload into ORM model allows attackers to overwrite administrative fields (e.g. is_admin, role)",
30
+ "severity": "high",
31
+ "cwe": "CWE-915",
32
+ "confidence": 0.9,
33
+ },
34
+ {
35
+ "id": "API-003",
36
+ "pattern": r"(?i)\b(redirect|HttpResponseRedirect)\s*\(\s*(request\.(GET|POST|args|query|params)\[?['\"]?(url|next|redirect|target|return_to)['\"]?\]?)\b",
37
+ "title": "Unvalidated open redirect via request query parameter (API8: SSRF / Open Redirect)",
38
+ "description": "Directly passing user-supplied URL to redirect without whitelist validation enables phishing and auth token leakage",
39
+ "severity": "medium",
40
+ "cwe": "CWE-601",
41
+ "confidence": 0.85,
42
+ },
43
+ {
44
+ "id": "API-004",
45
+ "pattern": r'(?i)@(app|router|api)\.(get|post)\s*\([^)]*["\']/(debug|metrics|actuator|healthcheck/full|_profiler|env|configdump)["\']\)',
46
+ "title": "Potentially exposed internal debug or diagnostic API endpoint",
47
+ "description": "Sensitive diagnostic endpoints exposed without strict network ACL or authentication guard",
48
+ "severity": "medium",
49
+ "cwe": "CWE-200",
50
+ "confidence": 0.85,
51
+ },
52
+ {
53
+ "id": "API-005",
54
+ "pattern": r'(?i)(jwt\.decode\s*\([^)]*options\s*=\s*\{.*verify_signature.*False.*\}|jwt\.decode\s*\([^)]*algorithms\s*=\s*\[\s*["\']none["\']\s*\]|verify\s*=\s*False)',
55
+ "title": "JWT signature verification explicitly disabled or 'none' algorithm accepted",
56
+ "description": "Accepting unsigned tokens or disabling cryptographic validation bypasses authentication completely",
57
+ "severity": "critical",
58
+ "cwe": "CWE-347",
59
+ "confidence": 0.95,
60
+ },
61
+ ]
62
+
63
+
64
+ class ApiSecurityEngine:
65
+ """100% custom, in-house developed REST API & Microservice Security Engine."""
66
+
67
+ name = "api_security"
68
+ version = "1.0.0"
69
+
70
+ def __init__(self):
71
+ self._compiled_rules = []
72
+ for r in API_RULES:
73
+ self._compiled_rules.append({
74
+ **r,
75
+ "regex": re.compile(r["pattern"])
76
+ })
77
+
78
+ async def check_availability(self) -> bool:
79
+ return True
80
+
81
+ def resource_limits(self) -> ResourceLimits:
82
+ return ResourceLimits(max_cpu_seconds=30, max_memory_mb=256)
83
+
84
+ async def run(self, ir: OrionIR, config: EngineConfig) -> EngineResult:
85
+ path = ir.metadata.get("path", "unknown")
86
+ try:
87
+ content = ir.content.decode("utf-8", errors="replace")
88
+ except Exception:
89
+ return EngineResult(engine=self.name, findings=[], ok=True)
90
+
91
+ lines = content.splitlines()
92
+ findings = []
93
+
94
+ for rule in self._compiled_rules:
95
+ for match in rule["regex"].finditer(content):
96
+ line_no = content[:match.start()].count('\n') + 1
97
+ start_line = max(0, line_no - 2)
98
+ end_line = min(len(lines), line_no + 2)
99
+ snippet = '\n'.join(lines[start_line:end_line])
100
+
101
+ findings.append(Finding(
102
+ engine=self.name,
103
+ severity=rule["severity"],
104
+ title=f"{rule['id']}: {rule['title']}",
105
+ description=rule["description"],
106
+ location=f"{path}:{line_no}",
107
+ metadata={
108
+ "rule_id": rule["id"],
109
+ "cwe": rule["cwe"],
110
+ "confidence": rule["confidence"],
111
+ "snippet": snippet,
112
+ "file": path,
113
+ "line": line_no,
114
+ }
115
+ ))
116
+
117
+ return EngineResult(
118
+ engine=self.name,
119
+ findings=findings,
120
+ ok=True,
121
+ metrics={"findings_count": len(findings)}
122
+ )
123
+
124
+
125
+ Engine = ApiSecurityEngine