aiwaf 0.1.8.9__tar.gz → 0.1.9.0.1__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.
Potentially problematic release.
This version of aiwaf might be problematic. Click here for more details.
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/PKG-INFO +53 -1
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/README.md +52 -0
- aiwaf-0.1.9.0.1/aiwaf/__init__.py +24 -0
- aiwaf-0.1.9.0.1/aiwaf/management/commands/aiwaf_diagnose.py +135 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/storage.py +31 -11
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf.egg-info/PKG-INFO +53 -1
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf.egg-info/SOURCES.txt +1 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/pyproject.toml +1 -1
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/setup.py +1 -1
- aiwaf-0.1.8.9/aiwaf/__init__.py +0 -1
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/LICENSE +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/apps.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/blacklist_manager.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/decorators.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/__init__.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/commands/__init__.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/commands/add_ipexemption.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/commands/aiwaf_logging.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/commands/aiwaf_reset.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/management/commands/detect_and_train.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/middleware.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/middleware_logger.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/models.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/resources/model.pkl +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/templatetags/__init__.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/templatetags/aiwaf_tags.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/trainer.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf/utils.py +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf.egg-info/dependency_links.txt +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf.egg-info/requires.txt +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/aiwaf.egg-info/top_level.txt +0 -0
- {aiwaf-0.1.8.9 → aiwaf-0.1.9.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiwaf
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9.0.1
|
|
4
4
|
Summary: AI-powered Web Application Firewall
|
|
5
5
|
Home-page: https://github.com/aayushgauba/aiwaf
|
|
6
6
|
Author: Aayush Gauba
|
|
@@ -324,6 +324,58 @@ MIDDLEWARE = [
|
|
|
324
324
|
|
|
325
325
|
> **⚠️ Order matters!** AI-WAF protection middleware should come early. The logger middleware should come near the end to capture final response data.
|
|
326
326
|
|
|
327
|
+
### **Troubleshooting Middleware Errors**
|
|
328
|
+
|
|
329
|
+
**Error: `Module "aiwaf.middleware" does not define a "UUIDTamperMiddleware" attribute/class`**
|
|
330
|
+
|
|
331
|
+
**Solutions:**
|
|
332
|
+
1. **Update AI-WAF to latest version:**
|
|
333
|
+
```bash
|
|
334
|
+
pip install --upgrade aiwaf
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
2. **Run diagnostic commands:**
|
|
338
|
+
```bash
|
|
339
|
+
# Quick debug script (from AI-WAF directory)
|
|
340
|
+
python debug_aiwaf.py
|
|
341
|
+
|
|
342
|
+
# Django management command
|
|
343
|
+
python manage.py aiwaf_diagnose
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
3. **Check available middleware classes:**
|
|
347
|
+
```python
|
|
348
|
+
# In Django shell: python manage.py shell
|
|
349
|
+
import aiwaf.middleware
|
|
350
|
+
print(dir(aiwaf.middleware))
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
4. **Verify AI-WAF is in INSTALLED_APPS:**
|
|
354
|
+
```python
|
|
355
|
+
# In settings.py
|
|
356
|
+
INSTALLED_APPS = [
|
|
357
|
+
# ... other apps ...
|
|
358
|
+
'aiwaf', # Must be included
|
|
359
|
+
]
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
5. **Use minimal middleware setup if needed:**
|
|
363
|
+
```python
|
|
364
|
+
MIDDLEWARE = [
|
|
365
|
+
# ... your existing middleware ...
|
|
366
|
+
"aiwaf.middleware.IPAndKeywordBlockMiddleware", # Core protection
|
|
367
|
+
"aiwaf.middleware.RateLimitMiddleware", # Rate limiting
|
|
368
|
+
"aiwaf.middleware.AIAnomalyMiddleware", # AI detection
|
|
369
|
+
]
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Common Issues:**
|
|
373
|
+
- **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
|
|
374
|
+
- Missing Django: `pip install Django`
|
|
375
|
+
- Old AI-WAF version: `pip install --upgrade aiwaf`
|
|
376
|
+
- Missing migrations: `python manage.py migrate`
|
|
377
|
+
- Import errors: Check `INSTALLED_APPS` includes `'aiwaf'`
|
|
378
|
+
|
|
327
379
|
---
|
|
328
380
|
|
|
329
381
|
## Running Detection & Training
|
|
@@ -303,6 +303,58 @@ MIDDLEWARE = [
|
|
|
303
303
|
|
|
304
304
|
> **⚠️ Order matters!** AI-WAF protection middleware should come early. The logger middleware should come near the end to capture final response data.
|
|
305
305
|
|
|
306
|
+
### **Troubleshooting Middleware Errors**
|
|
307
|
+
|
|
308
|
+
**Error: `Module "aiwaf.middleware" does not define a "UUIDTamperMiddleware" attribute/class`**
|
|
309
|
+
|
|
310
|
+
**Solutions:**
|
|
311
|
+
1. **Update AI-WAF to latest version:**
|
|
312
|
+
```bash
|
|
313
|
+
pip install --upgrade aiwaf
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
2. **Run diagnostic commands:**
|
|
317
|
+
```bash
|
|
318
|
+
# Quick debug script (from AI-WAF directory)
|
|
319
|
+
python debug_aiwaf.py
|
|
320
|
+
|
|
321
|
+
# Django management command
|
|
322
|
+
python manage.py aiwaf_diagnose
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
3. **Check available middleware classes:**
|
|
326
|
+
```python
|
|
327
|
+
# In Django shell: python manage.py shell
|
|
328
|
+
import aiwaf.middleware
|
|
329
|
+
print(dir(aiwaf.middleware))
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
4. **Verify AI-WAF is in INSTALLED_APPS:**
|
|
333
|
+
```python
|
|
334
|
+
# In settings.py
|
|
335
|
+
INSTALLED_APPS = [
|
|
336
|
+
# ... other apps ...
|
|
337
|
+
'aiwaf', # Must be included
|
|
338
|
+
]
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
5. **Use minimal middleware setup if needed:**
|
|
342
|
+
```python
|
|
343
|
+
MIDDLEWARE = [
|
|
344
|
+
# ... your existing middleware ...
|
|
345
|
+
"aiwaf.middleware.IPAndKeywordBlockMiddleware", # Core protection
|
|
346
|
+
"aiwaf.middleware.RateLimitMiddleware", # Rate limiting
|
|
347
|
+
"aiwaf.middleware.AIAnomalyMiddleware", # AI detection
|
|
348
|
+
]
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Common Issues:**
|
|
352
|
+
- **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
|
|
353
|
+
- Missing Django: `pip install Django`
|
|
354
|
+
- Old AI-WAF version: `pip install --upgrade aiwaf`
|
|
355
|
+
- Missing migrations: `python manage.py migrate`
|
|
356
|
+
- Import errors: Check `INSTALLED_APPS` includes `'aiwaf'`
|
|
357
|
+
|
|
306
358
|
---
|
|
307
359
|
|
|
308
360
|
## Running Detection & Training
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
default_app_config = "aiwaf.apps.AiwafConfig"
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.9.0.1"
|
|
4
|
+
|
|
5
|
+
# Note: Middleware classes are available from aiwaf.middleware
|
|
6
|
+
# Import them only when needed to avoid circular imports during Django app loading= "aiwaf.apps.AiwafConfig"
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.9.0.1"
|
|
9
|
+
|
|
10
|
+
# Import main middleware classes for easier access
|
|
11
|
+
try:
|
|
12
|
+
from .middleware import (
|
|
13
|
+
IPAndKeywordBlockMiddleware,
|
|
14
|
+
RateLimitMiddleware,
|
|
15
|
+
AIAnomalyMiddleware,
|
|
16
|
+
HoneypotTimingMiddleware,
|
|
17
|
+
UUIDTamperMiddleware
|
|
18
|
+
)
|
|
19
|
+
except ImportError as e:
|
|
20
|
+
# Handle import errors gracefully during package installation
|
|
21
|
+
import sys
|
|
22
|
+
if 'runserver' in sys.argv or 'migrate' in sys.argv or 'shell' in sys.argv:
|
|
23
|
+
print(f"Warning: Could not import middleware classes: {e}")
|
|
24
|
+
print("Tip: Run 'python manage.py aiwaf_diagnose' to troubleshoot")
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
class Command(BaseCommand):
|
|
6
|
+
help = 'Diagnose AI-WAF installation and middleware setup'
|
|
7
|
+
|
|
8
|
+
def handle(self, *args, **options):
|
|
9
|
+
self.stdout.write(self.style.HTTP_INFO("🔍 AI-WAF Installation Diagnostics"))
|
|
10
|
+
self.stdout.write("")
|
|
11
|
+
|
|
12
|
+
# Check AI-WAF import
|
|
13
|
+
try:
|
|
14
|
+
import aiwaf
|
|
15
|
+
version = getattr(aiwaf, '__version__', 'Unknown')
|
|
16
|
+
self.stdout.write(self.style.SUCCESS(f"✅ AI-WAF imported successfully (version: {version})"))
|
|
17
|
+
|
|
18
|
+
# Test critical imports that caused AppRegistryNotReady
|
|
19
|
+
try:
|
|
20
|
+
from aiwaf import storage, utils, trainer
|
|
21
|
+
self.stdout.write(self.style.SUCCESS("✅ Critical modules (storage, utils, trainer) imported successfully"))
|
|
22
|
+
except Exception as e:
|
|
23
|
+
self.stdout.write(self.style.ERROR(f"❌ Critical module import failed: {e}"))
|
|
24
|
+
|
|
25
|
+
except ImportError as e:
|
|
26
|
+
self.stdout.write(self.style.ERROR(f"❌ AI-WAF import failed: {e}"))
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
# Check if aiwaf is in INSTALLED_APPS
|
|
30
|
+
installed_apps = getattr(settings, 'INSTALLED_APPS', [])
|
|
31
|
+
if 'aiwaf' in installed_apps:
|
|
32
|
+
self.stdout.write(self.style.SUCCESS("✅ 'aiwaf' found in INSTALLED_APPS"))
|
|
33
|
+
else:
|
|
34
|
+
self.stdout.write(self.style.ERROR("❌ 'aiwaf' NOT found in INSTALLED_APPS"))
|
|
35
|
+
self.stdout.write(self.style.WARNING(" Add 'aiwaf' to your INSTALLED_APPS in settings.py"))
|
|
36
|
+
|
|
37
|
+
# Check middleware availability
|
|
38
|
+
self.stdout.write("")
|
|
39
|
+
self.stdout.write(self.style.HTTP_INFO("🧱 Middleware Availability Check:"))
|
|
40
|
+
|
|
41
|
+
middleware_classes = [
|
|
42
|
+
'IPAndKeywordBlockMiddleware',
|
|
43
|
+
'RateLimitMiddleware',
|
|
44
|
+
'AIAnomalyMiddleware',
|
|
45
|
+
'HoneypotTimingMiddleware',
|
|
46
|
+
'UUIDTamperMiddleware'
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
import aiwaf.middleware as mw
|
|
51
|
+
available_classes = dir(mw)
|
|
52
|
+
|
|
53
|
+
for middleware_class in middleware_classes:
|
|
54
|
+
if middleware_class in available_classes:
|
|
55
|
+
self.stdout.write(self.style.SUCCESS(f" ✅ {middleware_class}"))
|
|
56
|
+
else:
|
|
57
|
+
self.stdout.write(self.style.ERROR(f" ❌ {middleware_class} (missing)"))
|
|
58
|
+
except ImportError as e:
|
|
59
|
+
self.stdout.write(self.style.ERROR(f"❌ Could not import aiwaf.middleware: {e}"))
|
|
60
|
+
|
|
61
|
+
# Check configured middleware
|
|
62
|
+
self.stdout.write("")
|
|
63
|
+
self.stdout.write(self.style.HTTP_INFO("⚙️ Configured Middleware:"))
|
|
64
|
+
|
|
65
|
+
middleware_setting = getattr(settings, 'MIDDLEWARE', [])
|
|
66
|
+
aiwaf_middleware = [mw for mw in middleware_setting if 'aiwaf' in mw.lower()]
|
|
67
|
+
|
|
68
|
+
if aiwaf_middleware:
|
|
69
|
+
for mw in aiwaf_middleware:
|
|
70
|
+
# Test if middleware can be imported
|
|
71
|
+
try:
|
|
72
|
+
from django.utils.module_loading import import_string
|
|
73
|
+
import_string(mw)
|
|
74
|
+
self.stdout.write(self.style.SUCCESS(f" ✅ {mw}"))
|
|
75
|
+
except ImportError as e:
|
|
76
|
+
self.stdout.write(self.style.ERROR(f" ❌ {mw} - Import Error: {e}"))
|
|
77
|
+
except Exception as e:
|
|
78
|
+
self.stdout.write(self.style.WARNING(f" ⚠️ {mw} - Warning: {e}"))
|
|
79
|
+
else:
|
|
80
|
+
self.stdout.write(self.style.WARNING(" No AI-WAF middleware found in MIDDLEWARE setting"))
|
|
81
|
+
|
|
82
|
+
# Check storage configuration
|
|
83
|
+
self.stdout.write("")
|
|
84
|
+
self.stdout.write(self.style.HTTP_INFO("💾 Storage Configuration:"))
|
|
85
|
+
|
|
86
|
+
storage_mode = getattr(settings, 'AIWAF_STORAGE_MODE', 'models')
|
|
87
|
+
self.stdout.write(f" Storage Mode: {storage_mode}")
|
|
88
|
+
|
|
89
|
+
if storage_mode == 'csv':
|
|
90
|
+
csv_dir = getattr(settings, 'AIWAF_CSV_DATA_DIR', 'aiwaf_data')
|
|
91
|
+
self.stdout.write(f" CSV Directory: {csv_dir}")
|
|
92
|
+
|
|
93
|
+
# Check access log
|
|
94
|
+
access_log = getattr(settings, 'AIWAF_ACCESS_LOG', None)
|
|
95
|
+
if access_log:
|
|
96
|
+
import os
|
|
97
|
+
if os.path.exists(access_log):
|
|
98
|
+
self.stdout.write(self.style.SUCCESS(f" ✅ Access log found: {access_log}"))
|
|
99
|
+
else:
|
|
100
|
+
self.stdout.write(self.style.WARNING(f" ⚠️ Access log not found: {access_log}"))
|
|
101
|
+
else:
|
|
102
|
+
self.stdout.write(self.style.WARNING(" ⚠️ AIWAF_ACCESS_LOG not configured"))
|
|
103
|
+
|
|
104
|
+
# Check middleware logging
|
|
105
|
+
middleware_logging = getattr(settings, 'AIWAF_MIDDLEWARE_LOGGING', False)
|
|
106
|
+
if middleware_logging:
|
|
107
|
+
self.stdout.write(self.style.SUCCESS(" ✅ Middleware logging enabled"))
|
|
108
|
+
else:
|
|
109
|
+
self.stdout.write(self.style.WARNING(" ⚠️ Middleware logging disabled"))
|
|
110
|
+
|
|
111
|
+
# Recommendations
|
|
112
|
+
self.stdout.write("")
|
|
113
|
+
self.stdout.write(self.style.HTTP_INFO("💡 Recommendations:"))
|
|
114
|
+
|
|
115
|
+
if 'aiwaf' not in installed_apps:
|
|
116
|
+
self.stdout.write(" 1. Add 'aiwaf' to INSTALLED_APPS")
|
|
117
|
+
|
|
118
|
+
if not aiwaf_middleware:
|
|
119
|
+
self.stdout.write(" 2. Add AI-WAF middleware to MIDDLEWARE setting")
|
|
120
|
+
|
|
121
|
+
if not access_log and not middleware_logging:
|
|
122
|
+
self.stdout.write(" 3. Configure AIWAF_ACCESS_LOG or enable AIWAF_MIDDLEWARE_LOGGING")
|
|
123
|
+
|
|
124
|
+
# Quick fix commands
|
|
125
|
+
self.stdout.write("")
|
|
126
|
+
self.stdout.write(self.style.HTTP_INFO("🚀 Quick Fix Commands:"))
|
|
127
|
+
self.stdout.write("")
|
|
128
|
+
self.stdout.write("# Update AI-WAF to latest version:")
|
|
129
|
+
self.stdout.write("pip install --upgrade aiwaf")
|
|
130
|
+
self.stdout.write("")
|
|
131
|
+
self.stdout.write("# Run migrations (if using models mode):")
|
|
132
|
+
self.stdout.write("python manage.py migrate")
|
|
133
|
+
self.stdout.write("")
|
|
134
|
+
self.stdout.write("# Test AI-WAF commands:")
|
|
135
|
+
self.stdout.write("python manage.py add_ipexemption 127.0.0.1 --reason Testing")
|
|
@@ -4,17 +4,23 @@ import pandas as pd
|
|
|
4
4
|
from django.conf import settings
|
|
5
5
|
from django.utils import timezone
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
# Defer model imports to avoid AppRegistryNotReady during Django app loading
|
|
8
|
+
FeatureSample = BlacklistEntry = IPExemption = DynamicKeyword = None
|
|
9
|
+
|
|
10
|
+
def _import_models():
|
|
11
|
+
"""Import Django models only when needed and apps are ready."""
|
|
12
|
+
global FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
|
|
13
|
+
|
|
14
|
+
if FeatureSample is not None:
|
|
15
|
+
return # Already imported
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from django.apps import apps
|
|
19
|
+
if apps.ready and apps.is_installed('aiwaf'):
|
|
20
|
+
from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
|
|
21
|
+
except (ImportError, RuntimeError, Exception):
|
|
22
|
+
# Keep models as None if can't import
|
|
23
|
+
pass
|
|
18
24
|
|
|
19
25
|
# Configuration
|
|
20
26
|
STORAGE_MODE = getattr(settings, "AIWAF_STORAGE_MODE", "models") # "models" or "csv"
|
|
@@ -63,6 +69,7 @@ class CsvFeatureStore:
|
|
|
63
69
|
class DbFeatureStore:
|
|
64
70
|
@staticmethod
|
|
65
71
|
def persist_rows(rows):
|
|
72
|
+
_import_models()
|
|
66
73
|
if FeatureSample is not None:
|
|
67
74
|
objs = []
|
|
68
75
|
for ip,pl,kw,rt,si,bc,t404,label in rows:
|
|
@@ -76,6 +83,7 @@ class DbFeatureStore:
|
|
|
76
83
|
|
|
77
84
|
@staticmethod
|
|
78
85
|
def load_matrix():
|
|
86
|
+
_import_models()
|
|
79
87
|
if FeatureSample is not None:
|
|
80
88
|
qs = FeatureSample.objects.all().values_list(
|
|
81
89
|
"path_len","kw_hits","resp_time","status_idx","burst_count","total_404"
|
|
@@ -317,23 +325,27 @@ class ModelBlacklistStore:
|
|
|
317
325
|
|
|
318
326
|
@staticmethod
|
|
319
327
|
def add_ip(ip_address, reason):
|
|
328
|
+
_import_models()
|
|
320
329
|
if BlacklistEntry is not None:
|
|
321
330
|
BlacklistEntry.objects.get_or_create(ip_address=ip_address, defaults={"reason": reason})
|
|
322
331
|
|
|
323
332
|
@staticmethod
|
|
324
333
|
def is_blocked(ip_address):
|
|
334
|
+
_import_models()
|
|
325
335
|
if BlacklistEntry is not None:
|
|
326
336
|
return BlacklistEntry.objects.filter(ip_address=ip_address).exists()
|
|
327
337
|
return False
|
|
328
338
|
|
|
329
339
|
@staticmethod
|
|
330
340
|
def get_all():
|
|
341
|
+
_import_models()
|
|
331
342
|
if BlacklistEntry is not None:
|
|
332
343
|
return list(BlacklistEntry.objects.values("ip_address", "reason", "created_at"))
|
|
333
344
|
return []
|
|
334
345
|
|
|
335
346
|
@staticmethod
|
|
336
347
|
def remove_ip(ip_address):
|
|
348
|
+
_import_models()
|
|
337
349
|
if BlacklistEntry is not None:
|
|
338
350
|
BlacklistEntry.objects.filter(ip_address=ip_address).delete()
|
|
339
351
|
|
|
@@ -343,23 +355,27 @@ class ModelExemptionStore:
|
|
|
343
355
|
|
|
344
356
|
@staticmethod
|
|
345
357
|
def add_ip(ip_address, reason=""):
|
|
358
|
+
_import_models()
|
|
346
359
|
if IPExemption is not None:
|
|
347
360
|
IPExemption.objects.get_or_create(ip_address=ip_address, defaults={"reason": reason})
|
|
348
361
|
|
|
349
362
|
@staticmethod
|
|
350
363
|
def is_exempted(ip_address):
|
|
364
|
+
_import_models()
|
|
351
365
|
if IPExemption is not None:
|
|
352
366
|
return IPExemption.objects.filter(ip_address=ip_address).exists()
|
|
353
367
|
return False
|
|
354
368
|
|
|
355
369
|
@staticmethod
|
|
356
370
|
def get_all():
|
|
371
|
+
_import_models()
|
|
357
372
|
if IPExemption is not None:
|
|
358
373
|
return list(IPExemption.objects.values("ip_address", "reason", "created_at"))
|
|
359
374
|
return []
|
|
360
375
|
|
|
361
376
|
@staticmethod
|
|
362
377
|
def remove_ip(ip_address):
|
|
378
|
+
_import_models()
|
|
363
379
|
if IPExemption is not None:
|
|
364
380
|
IPExemption.objects.filter(ip_address=ip_address).delete()
|
|
365
381
|
|
|
@@ -369,6 +385,7 @@ class ModelKeywordStore:
|
|
|
369
385
|
|
|
370
386
|
@staticmethod
|
|
371
387
|
def add_keyword(keyword, count=1):
|
|
388
|
+
_import_models()
|
|
372
389
|
if DynamicKeyword is not None:
|
|
373
390
|
obj, created = DynamicKeyword.objects.get_or_create(keyword=keyword, defaults={"count": count})
|
|
374
391
|
if not created:
|
|
@@ -377,16 +394,19 @@ class ModelKeywordStore:
|
|
|
377
394
|
|
|
378
395
|
@staticmethod
|
|
379
396
|
def get_top_keywords(limit=10):
|
|
397
|
+
_import_models()
|
|
380
398
|
if DynamicKeyword is not None:
|
|
381
399
|
return list(DynamicKeyword.objects.order_by("-count").values_list("keyword", flat=True)[:limit])
|
|
382
400
|
return []
|
|
383
401
|
|
|
384
402
|
@staticmethod
|
|
385
403
|
def remove_keyword(keyword):
|
|
404
|
+
_import_models()
|
|
386
405
|
if DynamicKeyword is not None:
|
|
387
406
|
DynamicKeyword.objects.filter(keyword=keyword).delete()
|
|
388
407
|
|
|
389
408
|
@staticmethod
|
|
390
409
|
def clear_all():
|
|
410
|
+
_import_models()
|
|
391
411
|
if DynamicKeyword is not None:
|
|
392
412
|
DynamicKeyword.objects.all().delete()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiwaf
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9.0.1
|
|
4
4
|
Summary: AI-powered Web Application Firewall
|
|
5
5
|
Home-page: https://github.com/aayushgauba/aiwaf
|
|
6
6
|
Author: Aayush Gauba
|
|
@@ -324,6 +324,58 @@ MIDDLEWARE = [
|
|
|
324
324
|
|
|
325
325
|
> **⚠️ Order matters!** AI-WAF protection middleware should come early. The logger middleware should come near the end to capture final response data.
|
|
326
326
|
|
|
327
|
+
### **Troubleshooting Middleware Errors**
|
|
328
|
+
|
|
329
|
+
**Error: `Module "aiwaf.middleware" does not define a "UUIDTamperMiddleware" attribute/class`**
|
|
330
|
+
|
|
331
|
+
**Solutions:**
|
|
332
|
+
1. **Update AI-WAF to latest version:**
|
|
333
|
+
```bash
|
|
334
|
+
pip install --upgrade aiwaf
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
2. **Run diagnostic commands:**
|
|
338
|
+
```bash
|
|
339
|
+
# Quick debug script (from AI-WAF directory)
|
|
340
|
+
python debug_aiwaf.py
|
|
341
|
+
|
|
342
|
+
# Django management command
|
|
343
|
+
python manage.py aiwaf_diagnose
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
3. **Check available middleware classes:**
|
|
347
|
+
```python
|
|
348
|
+
# In Django shell: python manage.py shell
|
|
349
|
+
import aiwaf.middleware
|
|
350
|
+
print(dir(aiwaf.middleware))
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
4. **Verify AI-WAF is in INSTALLED_APPS:**
|
|
354
|
+
```python
|
|
355
|
+
# In settings.py
|
|
356
|
+
INSTALLED_APPS = [
|
|
357
|
+
# ... other apps ...
|
|
358
|
+
'aiwaf', # Must be included
|
|
359
|
+
]
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
5. **Use minimal middleware setup if needed:**
|
|
363
|
+
```python
|
|
364
|
+
MIDDLEWARE = [
|
|
365
|
+
# ... your existing middleware ...
|
|
366
|
+
"aiwaf.middleware.IPAndKeywordBlockMiddleware", # Core protection
|
|
367
|
+
"aiwaf.middleware.RateLimitMiddleware", # Rate limiting
|
|
368
|
+
"aiwaf.middleware.AIAnomalyMiddleware", # AI detection
|
|
369
|
+
]
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Common Issues:**
|
|
373
|
+
- **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
|
|
374
|
+
- Missing Django: `pip install Django`
|
|
375
|
+
- Old AI-WAF version: `pip install --upgrade aiwaf`
|
|
376
|
+
- Missing migrations: `python manage.py migrate`
|
|
377
|
+
- Import errors: Check `INSTALLED_APPS` includes `'aiwaf'`
|
|
378
|
+
|
|
327
379
|
---
|
|
328
380
|
|
|
329
381
|
## Running Detection & Training
|
|
@@ -20,6 +20,7 @@ aiwaf.egg-info/top_level.txt
|
|
|
20
20
|
aiwaf/management/__init__.py
|
|
21
21
|
aiwaf/management/commands/__init__.py
|
|
22
22
|
aiwaf/management/commands/add_ipexemption.py
|
|
23
|
+
aiwaf/management/commands/aiwaf_diagnose.py
|
|
23
24
|
aiwaf/management/commands/aiwaf_logging.py
|
|
24
25
|
aiwaf/management/commands/aiwaf_reset.py
|
|
25
26
|
aiwaf/management/commands/detect_and_train.py
|
|
@@ -9,7 +9,7 @@ long_description = (HERE / "README.md").read_text(encoding="utf-8")
|
|
|
9
9
|
|
|
10
10
|
setup(
|
|
11
11
|
name="aiwaf",
|
|
12
|
-
version="0.1.
|
|
12
|
+
version="0.1.9.0.1",
|
|
13
13
|
description="AI‑driven, self‑learning Web Application Firewall for Django",
|
|
14
14
|
long_description=long_description,
|
|
15
15
|
long_description_content_type="text/markdown",
|
aiwaf-0.1.8.9/aiwaf/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
default_app_config = "aiwaf.apps.AiwafConfig"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|