inject-bender 0.3.0__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.
- inject_bender-0.3.0/.gitignore +74 -0
- inject_bender-0.3.0/PKG-INFO +132 -0
- inject_bender-0.3.0/README.md +90 -0
- inject_bender-0.3.0/pyproject.toml +55 -0
- inject_bender-0.3.0/src/inject_bender/__init__.py +84 -0
- inject_bender-0.3.0/src/inject_bender/bender.py +200 -0
- inject_bender-0.3.0/src/inject_bender/cli.py +182 -0
- inject_bender-0.3.0/src/inject_bender/comedy.py +128 -0
- inject_bender-0.3.0/src/inject_bender/detector.py +169 -0
- inject_bender-0.3.0/src/inject_bender/legal.py +388 -0
- inject_bender-0.3.0/src/inject_bender/middleware.py +158 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Secrets & env
|
|
2
|
+
.env
|
|
3
|
+
*.env
|
|
4
|
+
*.secret
|
|
5
|
+
|
|
6
|
+
# Keys & certs
|
|
7
|
+
*.key
|
|
8
|
+
*.pem
|
|
9
|
+
certs/
|
|
10
|
+
secrets/
|
|
11
|
+
|
|
12
|
+
# Databases & dumps
|
|
13
|
+
*.db
|
|
14
|
+
*.sqlite
|
|
15
|
+
*.sql
|
|
16
|
+
dump_*/
|
|
17
|
+
|
|
18
|
+
# EXCEPT: Allow database schemas (needed for server rebuild)
|
|
19
|
+
!database-schemas/*.sql
|
|
20
|
+
|
|
21
|
+
# Logs & runtime data
|
|
22
|
+
logs/
|
|
23
|
+
*.log
|
|
24
|
+
__pycache__/
|
|
25
|
+
*.pyc
|
|
26
|
+
venv/
|
|
27
|
+
.venv/
|
|
28
|
+
**/venv/
|
|
29
|
+
**/.venv/
|
|
30
|
+
|
|
31
|
+
# Configs met secrets (we gebruiken straks templates)
|
|
32
|
+
config/
|
|
33
|
+
brain_api/provisioning.local.json
|
|
34
|
+
brain_api/provisioning.json
|
|
35
|
+
|
|
36
|
+
# Landing pages (privé - niet open source)
|
|
37
|
+
landing-pages/
|
|
38
|
+
humotica.com/
|
|
39
|
+
jtel.nl/
|
|
40
|
+
|
|
41
|
+
# Social media posts (strategie - niet open source)
|
|
42
|
+
SOCIAL-MEDIA-POSTS.md
|
|
43
|
+
HN-POST-UNDER-4000.md
|
|
44
|
+
STRATO-DEPLOY-HUMOTICA.md
|
|
45
|
+
|
|
46
|
+
# Endorsement outreach (privaat contact)
|
|
47
|
+
ARXIV-ENDORSEMENT-OUTREACH.md
|
|
48
|
+
|
|
49
|
+
# Deployment secrets
|
|
50
|
+
DEPLOYMENT-GUIDE.md
|
|
51
|
+
|
|
52
|
+
# R Project files (Dirty Data Challenge)
|
|
53
|
+
.Rproj.user
|
|
54
|
+
.Rhistory
|
|
55
|
+
.RData
|
|
56
|
+
.Ruserdata
|
|
57
|
+
*.zip
|
|
58
|
+
.mural_tokens.json
|
|
59
|
+
auth.json
|
|
60
|
+
gen-lang-client*.json
|
|
61
|
+
*.credentials.json
|
|
62
|
+
|
|
63
|
+
# Rust build artifacts
|
|
64
|
+
**/target/
|
|
65
|
+
*.whl
|
|
66
|
+
|
|
67
|
+
# Compiled binaries (build locally)
|
|
68
|
+
jis-router/jis-router
|
|
69
|
+
sentinel-rs/sentinel-rs
|
|
70
|
+
|
|
71
|
+
# Build distribution
|
|
72
|
+
sandbox/ai/codex/dist/
|
|
73
|
+
sandbox_backup/
|
|
74
|
+
did-jis-core
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inject-bender
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Security input validation with dual response modes: legal deterrence (NIS2/GDPR compliant audit trail) or comedy (hiking boots for hackers). TIBET provenance. OWASP aware.
|
|
5
|
+
Project-URL: Homepage, https://humotica.com
|
|
6
|
+
Project-URL: Repository, https://github.com/jaspertvdm/inject-bender
|
|
7
|
+
Project-URL: Documentation, https://humotica.com/docs/inject-bender
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/jaspertvdm/inject-bender/issues
|
|
9
|
+
Project-URL: OWASP Top 10, https://owasp.org/www-project-top-ten/
|
|
10
|
+
Project-URL: NIS2 Directive, https://digital-strategy.ec.europa.eu/en/policies/nis2-directive
|
|
11
|
+
Author-email: "J. van de Meent" <jasper@humotica.com>, "R. AI" <root_idd@humotica.nl>
|
|
12
|
+
Maintainer-email: Humotica AI Lab <ai@humotica.nl>
|
|
13
|
+
License: MIT
|
|
14
|
+
Keywords: audit,compliance,detection,deterrence,gdpr,injection,input-validation,legal,nis2,owasp,prompt-injection,provenance,security,sql-injection,tibet,waf,xss
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Intended Audience :: System Administrators
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
24
|
+
Classifier: Topic :: Security
|
|
25
|
+
Classifier: Topic :: System :: Logging
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Provides-Extra: ai
|
|
28
|
+
Requires-Dist: httpx>=0.24.0; extra == 'ai'
|
|
29
|
+
Provides-Extra: api
|
|
30
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'api'
|
|
31
|
+
Requires-Dist: httpx>=0.24.0; extra == 'api'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
35
|
+
Provides-Extra: full
|
|
36
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'full'
|
|
37
|
+
Requires-Dist: httpx>=0.24.0; extra == 'full'
|
|
38
|
+
Requires-Dist: tibet-core>=0.2.0; extra == 'full'
|
|
39
|
+
Provides-Extra: tibet
|
|
40
|
+
Requires-Dist: tibet-core>=0.2.0; extra == 'tibet'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# inject-bender
|
|
44
|
+
|
|
45
|
+
Security input validation with dual response modes: **legal deterrence** (NIS2/GDPR compliant audit trail) or **comedy** (hiking boots for hackers).
|
|
46
|
+
|
|
47
|
+
Every detected attack is logged with [TIBET](https://pypi.org/project/tibet-core/) provenance tokens.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install inject-bender
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
With TIBET audit trail:
|
|
56
|
+
```bash
|
|
57
|
+
pip install inject-bender[tibet]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
With FastAPI middleware:
|
|
61
|
+
```bash
|
|
62
|
+
pip install inject-bender[api]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from inject_bender import InjectBender
|
|
69
|
+
|
|
70
|
+
bender = InjectBender(mode="legal") # or "comedy"
|
|
71
|
+
result = bender.bend("'; DROP TABLE users; --")
|
|
72
|
+
|
|
73
|
+
if result["was_attack"]:
|
|
74
|
+
print(result["formatted"])
|
|
75
|
+
print(f"Incident: {result['incident_id']}")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Detection Only
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from inject_bender import detect
|
|
82
|
+
|
|
83
|
+
is_attack, attack_type = detect("SELECT * FROM users WHERE 1=1")
|
|
84
|
+
# (True, "sql_injection")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Modes
|
|
88
|
+
|
|
89
|
+
| Mode | Response | Use Case |
|
|
90
|
+
|------|----------|----------|
|
|
91
|
+
| `legal` | Law citations, NIS2 audit trail, incident reports | Production, enterprise |
|
|
92
|
+
| `comedy` | Hiking boot ads (Skippie & Odin) | Development, demos, honeypots |
|
|
93
|
+
| `silent` | Detect and log only | Monitoring, WAF integration |
|
|
94
|
+
| `custom` | Your own response function | Any |
|
|
95
|
+
|
|
96
|
+
## ASGI Middleware
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from fastapi import FastAPI
|
|
100
|
+
from inject_bender.middleware import InjectBenderMiddleware
|
|
101
|
+
|
|
102
|
+
app = FastAPI()
|
|
103
|
+
app.add_middleware(InjectBenderMiddleware, mode="legal")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## CLI
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
inject-bender check "'; DROP TABLE users; --"
|
|
110
|
+
inject-bender bend --mode comedy "<script>alert('xss')</script>"
|
|
111
|
+
inject-bender laws
|
|
112
|
+
inject-bender demo
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Attack Types Detected
|
|
116
|
+
|
|
117
|
+
SQL Injection, XSS, Command Injection, Path Traversal, Prompt Injection, LDAP Injection, XML/XXE, Header Injection, Template Injection (SSTI).
|
|
118
|
+
|
|
119
|
+
## NIS2 Compliance
|
|
120
|
+
|
|
121
|
+
- Automatic incident detection and logging
|
|
122
|
+
- Immutable TIBET audit trail
|
|
123
|
+
- Report generation: NIS2, AP (Autoriteit Persoonsgegevens), Politie
|
|
124
|
+
- 24-hour deadline tracking
|
|
125
|
+
|
|
126
|
+
## Legal Mapping
|
|
127
|
+
|
|
128
|
+
Dutch/EU criminal law per attack type: Sr art. 138ab (computervredebreuk), Sr art. 350a (gegevensvernieling), AVG/GDPR art. 32/33/34, EU AI Act, EU 2013/40.
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT — Humotica AI Lab 2025-2026
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# inject-bender
|
|
2
|
+
|
|
3
|
+
Security input validation with dual response modes: **legal deterrence** (NIS2/GDPR compliant audit trail) or **comedy** (hiking boots for hackers).
|
|
4
|
+
|
|
5
|
+
Every detected attack is logged with [TIBET](https://pypi.org/project/tibet-core/) provenance tokens.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install inject-bender
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
With TIBET audit trail:
|
|
14
|
+
```bash
|
|
15
|
+
pip install inject-bender[tibet]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
With FastAPI middleware:
|
|
19
|
+
```bash
|
|
20
|
+
pip install inject-bender[api]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from inject_bender import InjectBender
|
|
27
|
+
|
|
28
|
+
bender = InjectBender(mode="legal") # or "comedy"
|
|
29
|
+
result = bender.bend("'; DROP TABLE users; --")
|
|
30
|
+
|
|
31
|
+
if result["was_attack"]:
|
|
32
|
+
print(result["formatted"])
|
|
33
|
+
print(f"Incident: {result['incident_id']}")
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Detection Only
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from inject_bender import detect
|
|
40
|
+
|
|
41
|
+
is_attack, attack_type = detect("SELECT * FROM users WHERE 1=1")
|
|
42
|
+
# (True, "sql_injection")
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Modes
|
|
46
|
+
|
|
47
|
+
| Mode | Response | Use Case |
|
|
48
|
+
|------|----------|----------|
|
|
49
|
+
| `legal` | Law citations, NIS2 audit trail, incident reports | Production, enterprise |
|
|
50
|
+
| `comedy` | Hiking boot ads (Skippie & Odin) | Development, demos, honeypots |
|
|
51
|
+
| `silent` | Detect and log only | Monitoring, WAF integration |
|
|
52
|
+
| `custom` | Your own response function | Any |
|
|
53
|
+
|
|
54
|
+
## ASGI Middleware
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from fastapi import FastAPI
|
|
58
|
+
from inject_bender.middleware import InjectBenderMiddleware
|
|
59
|
+
|
|
60
|
+
app = FastAPI()
|
|
61
|
+
app.add_middleware(InjectBenderMiddleware, mode="legal")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## CLI
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
inject-bender check "'; DROP TABLE users; --"
|
|
68
|
+
inject-bender bend --mode comedy "<script>alert('xss')</script>"
|
|
69
|
+
inject-bender laws
|
|
70
|
+
inject-bender demo
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Attack Types Detected
|
|
74
|
+
|
|
75
|
+
SQL Injection, XSS, Command Injection, Path Traversal, Prompt Injection, LDAP Injection, XML/XXE, Header Injection, Template Injection (SSTI).
|
|
76
|
+
|
|
77
|
+
## NIS2 Compliance
|
|
78
|
+
|
|
79
|
+
- Automatic incident detection and logging
|
|
80
|
+
- Immutable TIBET audit trail
|
|
81
|
+
- Report generation: NIS2, AP (Autoriteit Persoonsgegevens), Politie
|
|
82
|
+
- 24-hour deadline tracking
|
|
83
|
+
|
|
84
|
+
## Legal Mapping
|
|
85
|
+
|
|
86
|
+
Dutch/EU criminal law per attack type: Sr art. 138ab (computervredebreuk), Sr art. 350a (gegevensvernieling), AVG/GDPR art. 32/33/34, EU AI Act, EU 2013/40.
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT — Humotica AI Lab 2025-2026
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "inject-bender"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Security input validation with dual response modes: legal deterrence (NIS2/GDPR compliant audit trail) or comedy (hiking boots for hackers). TIBET provenance. OWASP aware."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "J. van de Meent", email = "jasper@humotica.com" },
|
|
14
|
+
{ name = "R. AI", email = "root_idd@humotica.nl" },
|
|
15
|
+
]
|
|
16
|
+
maintainers = [
|
|
17
|
+
{ name = "Humotica AI Lab", email = "ai@humotica.nl" },
|
|
18
|
+
]
|
|
19
|
+
keywords = [
|
|
20
|
+
"security", "injection", "detection", "owasp", "nis2", "gdpr",
|
|
21
|
+
"audit", "tibet", "provenance", "compliance", "waf", "input-validation",
|
|
22
|
+
"sql-injection", "xss", "prompt-injection", "legal", "deterrence",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Intended Audience :: System Administrators",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3.10",
|
|
31
|
+
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Topic :: Security",
|
|
34
|
+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
35
|
+
"Topic :: System :: Logging",
|
|
36
|
+
]
|
|
37
|
+
dependencies = []
|
|
38
|
+
|
|
39
|
+
[project.optional-dependencies]
|
|
40
|
+
tibet = ["tibet-core>=0.2.0"]
|
|
41
|
+
api = ["fastapi>=0.100.0", "httpx>=0.24.0"]
|
|
42
|
+
ai = ["httpx>=0.24.0"]
|
|
43
|
+
full = ["tibet-core>=0.2.0", "fastapi>=0.100.0", "httpx>=0.24.0"]
|
|
44
|
+
dev = ["pytest>=7.0", "ruff>=0.1.0"]
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
inject-bender = "inject_bender.cli:main"
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
Homepage = "https://humotica.com"
|
|
51
|
+
Repository = "https://github.com/jaspertvdm/inject-bender"
|
|
52
|
+
Documentation = "https://humotica.com/docs/inject-bender"
|
|
53
|
+
"Bug Tracker" = "https://github.com/jaspertvdm/inject-bender/issues"
|
|
54
|
+
"OWASP Top 10" = "https://owasp.org/www-project-top-ten/"
|
|
55
|
+
"NIS2 Directive" = "https://digital-strategy.ec.europa.eu/en/policies/nis2-directive"
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""
|
|
2
|
+
inject-bender — Security Input Validation with Dual Response Modes
|
|
3
|
+
===================================================================
|
|
4
|
+
|
|
5
|
+
Legal deterrence (NIS2/GDPR compliant) or comedy (hiking boots for hackers).
|
|
6
|
+
Every attack is logged with TIBET provenance tokens.
|
|
7
|
+
|
|
8
|
+
Quick start — one line::
|
|
9
|
+
|
|
10
|
+
from inject_bender import InjectBender
|
|
11
|
+
|
|
12
|
+
bender = InjectBender(mode="legal") # or "comedy"
|
|
13
|
+
result = bender.bend("'; DROP TABLE users; --")
|
|
14
|
+
|
|
15
|
+
if result["was_attack"]:
|
|
16
|
+
print(result["formatted"])
|
|
17
|
+
|
|
18
|
+
Detection only::
|
|
19
|
+
|
|
20
|
+
from inject_bender import detect
|
|
21
|
+
|
|
22
|
+
is_attack, attack_type = detect("SELECT * FROM users")
|
|
23
|
+
|
|
24
|
+
ASGI middleware::
|
|
25
|
+
|
|
26
|
+
from inject_bender.middleware import InjectBenderMiddleware
|
|
27
|
+
|
|
28
|
+
app = FastAPI()
|
|
29
|
+
app.add_middleware(InjectBenderMiddleware, mode="legal")
|
|
30
|
+
|
|
31
|
+
Modes:
|
|
32
|
+
- **legal**: Law citations (Sr 138ab, AVG, AI Act), NIS2 incident reports,
|
|
33
|
+
court-admissible TIBET audit trail. Default mode.
|
|
34
|
+
- **comedy**: Hiking boot advertisements (Skippie & Odin guardians).
|
|
35
|
+
Because nothing confuses hackers more than getting boots for their injection.
|
|
36
|
+
- **silent**: Detect and log only, no response formatting.
|
|
37
|
+
- **custom**: Provide your own response_fn(attack_type, input) -> dict.
|
|
38
|
+
|
|
39
|
+
NIS2 Compliance:
|
|
40
|
+
- Automatic incident detection and logging
|
|
41
|
+
- Immutable TIBET audit trail per incident
|
|
42
|
+
- Report generation: NIS2, AP (datalek), Politie (aangifte)
|
|
43
|
+
- 24-hour deadline tracking
|
|
44
|
+
|
|
45
|
+
Authors: J. van de Meent & R. AI (Root AI)
|
|
46
|
+
License: MIT — Humotica AI Lab 2025-2026
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from .bender import InjectBender
|
|
50
|
+
from .detector import detect, detect_all, get_attack_name
|
|
51
|
+
from .legal import (
|
|
52
|
+
get_legal_info,
|
|
53
|
+
generate_legal_response,
|
|
54
|
+
format_legal_response,
|
|
55
|
+
IncidentStore,
|
|
56
|
+
generate_nis2_report,
|
|
57
|
+
generate_ap_report,
|
|
58
|
+
generate_police_report,
|
|
59
|
+
LEGAL_MAPPING,
|
|
60
|
+
)
|
|
61
|
+
from .comedy import get_comedy_response, format_comedy_response
|
|
62
|
+
|
|
63
|
+
__version__ = "0.3.0"
|
|
64
|
+
|
|
65
|
+
__all__ = [
|
|
66
|
+
# Main class
|
|
67
|
+
"InjectBender",
|
|
68
|
+
# Detection
|
|
69
|
+
"detect",
|
|
70
|
+
"detect_all",
|
|
71
|
+
"get_attack_name",
|
|
72
|
+
# Legal
|
|
73
|
+
"get_legal_info",
|
|
74
|
+
"generate_legal_response",
|
|
75
|
+
"format_legal_response",
|
|
76
|
+
"IncidentStore",
|
|
77
|
+
"generate_nis2_report",
|
|
78
|
+
"generate_ap_report",
|
|
79
|
+
"generate_police_report",
|
|
80
|
+
"LEGAL_MAPPING",
|
|
81
|
+
# Comedy
|
|
82
|
+
"get_comedy_response",
|
|
83
|
+
"format_comedy_response",
|
|
84
|
+
]
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
inject_bender.bender — Core Bender Engine
|
|
3
|
+
==========================================
|
|
4
|
+
|
|
5
|
+
The main InjectBender class that ties detection, legal, and comedy together.
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from inject_bender import InjectBender
|
|
10
|
+
|
|
11
|
+
bender = InjectBender(mode="legal") # or "comedy"
|
|
12
|
+
result = bender.bend("'; DROP TABLE users; --")
|
|
13
|
+
|
|
14
|
+
if result["was_attack"]:
|
|
15
|
+
print(result["formatted"])
|
|
16
|
+
print(f"Incident: {result['incident_id']}")
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
from typing import Optional, Dict, Any
|
|
22
|
+
|
|
23
|
+
from . import detector
|
|
24
|
+
from . import legal
|
|
25
|
+
from . import comedy
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class InjectBender:
|
|
29
|
+
"""
|
|
30
|
+
Security input validation with dual response modes.
|
|
31
|
+
|
|
32
|
+
Modes:
|
|
33
|
+
- "legal": Law citations, NIS2 audit trail, court-admissible records
|
|
34
|
+
- "comedy": Hiking boot ads (Skippie & Odin)
|
|
35
|
+
- "silent": Detect only, no response formatting
|
|
36
|
+
- "custom": Use your own response_fn(attack_type, input) -> dict
|
|
37
|
+
|
|
38
|
+
All modes create an audit record. Legal mode is the default.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
mode: str = "legal",
|
|
44
|
+
response_fn=None,
|
|
45
|
+
tibet_logger=None,
|
|
46
|
+
):
|
|
47
|
+
self.mode = mode
|
|
48
|
+
self.response_fn = response_fn
|
|
49
|
+
self.tibet_logger = tibet_logger
|
|
50
|
+
self.incidents = legal.IncidentStore()
|
|
51
|
+
self._attack_count = 0
|
|
52
|
+
self._stats: Dict[str, int] = {}
|
|
53
|
+
|
|
54
|
+
def bend(
|
|
55
|
+
self,
|
|
56
|
+
input_string: str,
|
|
57
|
+
client_ip: str = "",
|
|
58
|
+
mode: Optional[str] = None,
|
|
59
|
+
) -> dict:
|
|
60
|
+
"""
|
|
61
|
+
Analyze input and generate appropriate response.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
input_string: The user input to check
|
|
65
|
+
client_ip: Optional client IP for incident logging
|
|
66
|
+
mode: Override instance mode for this call
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Dict with was_attack, attack_type, formatted response, incident_id, etc.
|
|
70
|
+
"""
|
|
71
|
+
active_mode = mode or self.mode
|
|
72
|
+
|
|
73
|
+
# Detect
|
|
74
|
+
is_attack, attack_type = detector.detect(input_string)
|
|
75
|
+
|
|
76
|
+
if not is_attack:
|
|
77
|
+
return {
|
|
78
|
+
"was_attack": False,
|
|
79
|
+
"mode": active_mode,
|
|
80
|
+
"message": "Clean input - no attack detected.",
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Attack found
|
|
84
|
+
self._attack_count += 1
|
|
85
|
+
self._stats[attack_type] = self._stats.get(attack_type, 0) + 1
|
|
86
|
+
|
|
87
|
+
# Create TIBET token if available
|
|
88
|
+
token_id = self._create_tibet_token(attack_type, input_string)
|
|
89
|
+
|
|
90
|
+
# Store incident
|
|
91
|
+
incident = self.incidents.store(
|
|
92
|
+
attack_type=attack_type,
|
|
93
|
+
client_ip=client_ip,
|
|
94
|
+
token_id=token_id,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Build response based on mode
|
|
98
|
+
if active_mode == "legal":
|
|
99
|
+
legal_resp = legal.generate_legal_response(
|
|
100
|
+
attack_type=attack_type,
|
|
101
|
+
token_id=token_id,
|
|
102
|
+
incident_id=incident["incident_id"],
|
|
103
|
+
timestamp=incident["timestamp"],
|
|
104
|
+
)
|
|
105
|
+
return {
|
|
106
|
+
"was_attack": True,
|
|
107
|
+
"mode": "legal",
|
|
108
|
+
"attack_type": attack_type,
|
|
109
|
+
"attack_name": detector.get_attack_name(attack_type),
|
|
110
|
+
"legal_response": legal_resp,
|
|
111
|
+
"formatted": legal.format_legal_response(legal_resp),
|
|
112
|
+
"tibet_token_id": token_id,
|
|
113
|
+
"incident_id": incident["incident_id"],
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
elif active_mode == "comedy":
|
|
117
|
+
comedy_resp = comedy.get_comedy_response(attack_type)
|
|
118
|
+
return {
|
|
119
|
+
"was_attack": True,
|
|
120
|
+
"mode": "comedy",
|
|
121
|
+
"attack_type": attack_type,
|
|
122
|
+
"attack_name": detector.get_attack_name(attack_type),
|
|
123
|
+
"comedy_response": comedy_resp,
|
|
124
|
+
"formatted": comedy.format_comedy_response(comedy_resp),
|
|
125
|
+
"tibet_token_id": token_id,
|
|
126
|
+
"incident_id": incident["incident_id"],
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
elif active_mode == "custom" and self.response_fn:
|
|
130
|
+
custom_resp = self.response_fn(attack_type, input_string)
|
|
131
|
+
return {
|
|
132
|
+
"was_attack": True,
|
|
133
|
+
"mode": "custom",
|
|
134
|
+
"attack_type": attack_type,
|
|
135
|
+
"attack_name": detector.get_attack_name(attack_type),
|
|
136
|
+
"custom_response": custom_resp,
|
|
137
|
+
"tibet_token_id": token_id,
|
|
138
|
+
"incident_id": incident["incident_id"],
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
else:
|
|
142
|
+
# silent mode
|
|
143
|
+
return {
|
|
144
|
+
"was_attack": True,
|
|
145
|
+
"mode": "silent",
|
|
146
|
+
"attack_type": attack_type,
|
|
147
|
+
"attack_name": detector.get_attack_name(attack_type),
|
|
148
|
+
"tibet_token_id": token_id,
|
|
149
|
+
"incident_id": incident["incident_id"],
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
def check(self, input_string: str) -> dict:
|
|
153
|
+
"""Check input without generating a response. Lightweight detection only."""
|
|
154
|
+
is_attack, attack_type = detector.detect(input_string)
|
|
155
|
+
return {
|
|
156
|
+
"is_attack": is_attack,
|
|
157
|
+
"attack_type": attack_type,
|
|
158
|
+
"attack_name": detector.get_attack_name(attack_type) if attack_type else None,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
def check_all(self, input_string: str) -> dict:
|
|
162
|
+
"""Detect ALL attack types present in input."""
|
|
163
|
+
found = detector.detect_all(input_string)
|
|
164
|
+
return {
|
|
165
|
+
"is_attack": len(found) > 0,
|
|
166
|
+
"attack_types": found,
|
|
167
|
+
"attack_names": [detector.get_attack_name(t) for t in found],
|
|
168
|
+
"count": len(found),
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
def get_stats(self) -> dict:
|
|
172
|
+
"""Get bending statistics."""
|
|
173
|
+
return {
|
|
174
|
+
"total_attacks_detected": self._attack_count,
|
|
175
|
+
"attack_types": dict(self._stats),
|
|
176
|
+
"incidents_stored": self.incidents.count,
|
|
177
|
+
"mode": self.mode,
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
def _create_tibet_token(self, attack_type: str, input_string: str) -> str:
|
|
181
|
+
"""Create a TIBET token for the incident."""
|
|
182
|
+
# Try tibet-core integration
|
|
183
|
+
if self.tibet_logger:
|
|
184
|
+
try:
|
|
185
|
+
token = self.tibet_logger.create_token(
|
|
186
|
+
token_type="security_incident",
|
|
187
|
+
intent=f"detect_{attack_type}",
|
|
188
|
+
reason=f"Detected {detector.get_attack_name(attack_type)}",
|
|
189
|
+
source="inject_bender",
|
|
190
|
+
)
|
|
191
|
+
if hasattr(token, "token_id"):
|
|
192
|
+
return token.token_id
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
# Fallback: generate local token ID
|
|
197
|
+
token_id = hashlib.sha256(
|
|
198
|
+
f"{datetime.now().isoformat()}{input_string}{attack_type}".encode()
|
|
199
|
+
).hexdigest()[:16]
|
|
200
|
+
return f"BENT_{token_id}"
|