aiwaf 0.1.7.8__tar.gz → 0.1.8.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.

Files changed (27) hide show
  1. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/PKG-INFO +27 -24
  2. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/README.md +26 -23
  3. aiwaf-0.1.8.1/aiwaf/management/commands/aiwaf_reset.py +84 -0
  4. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/middleware.py +29 -8
  5. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf.egg-info/PKG-INFO +27 -24
  6. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf.egg-info/SOURCES.txt +1 -0
  7. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/pyproject.toml +1 -1
  8. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/setup.py +1 -1
  9. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/LICENSE +0 -0
  10. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/__init__.py +0 -0
  11. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/apps.py +0 -0
  12. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/blacklist_manager.py +0 -0
  13. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/management/__init__.py +0 -0
  14. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/management/commands/__init__.py +0 -0
  15. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/management/commands/add_ipexemption.py +0 -0
  16. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/management/commands/detect_and_train.py +0 -0
  17. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/models.py +0 -0
  18. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/resources/model.pkl +0 -0
  19. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/storage.py +0 -0
  20. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/templatetags/__init__.py +0 -0
  21. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/templatetags/aiwaf_tags.py +0 -0
  22. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/trainer.py +0 -0
  23. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf/utils.py +0 -0
  24. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf.egg-info/dependency_links.txt +0 -0
  25. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf.egg-info/requires.txt +0 -0
  26. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/aiwaf.egg-info/top_level.txt +0 -0
  27. {aiwaf-0.1.7.8 → aiwaf-0.1.8.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.7.8
3
+ Version: 0.1.8.1
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -77,8 +77,10 @@ aiwaf/
77
77
  - **File‑Extension Probing Detection**
78
78
  Tracks repeated 404s on common extensions (e.g. `.php`, `.asp`) and blocks IPs.
79
79
 
80
- - **Honeypot Field**
81
- Hidden field for bot detection IP blacklisted on fill.
80
+ - **Timing-Based Honeypot**
81
+ Tracks GET→POST timing patterns. Blocks IPs that:
82
+ - POST directly without a preceding GET request
83
+ - Submit forms faster than `AIWAF_MIN_FORM_TIME` seconds (default: 1 second)
82
84
 
83
85
  - **UUID Tampering Protection**
84
86
  Blocks guessed or invalid UUIDs that don’t resolve to real models.
@@ -107,6 +109,24 @@ Add an IP to the exemption list using the management command:
107
109
  python manage.py add_ipexemption <ip-address> --reason "optional reason"
108
110
  ```
109
111
 
112
+ ### Resetting AI-WAF
113
+
114
+ Clear all blacklist and exemption entries:
115
+
116
+ ```bash
117
+ # Clear everything (with confirmation prompt)
118
+ python manage.py aiwaf_reset
119
+
120
+ # Clear everything without confirmation
121
+ python manage.py aiwaf_reset --confirm
122
+
123
+ # Clear only blacklist entries
124
+ python manage.py aiwaf_reset --blacklist-only
125
+
126
+ # Clear only exemption entries
127
+ python manage.py aiwaf_reset --exemptions-only
128
+ ```
129
+
110
130
  This will ensure the IP is never blocked by AI‑WAF. You can also manage exemptions via the Django admin interface.
111
131
 
112
132
  - **Daily Retraining**
@@ -143,7 +163,7 @@ AIWAF_ACCESS_LOG = "/var/log/nginx/access.log"
143
163
 
144
164
  ```python
145
165
  AIWAF_MODEL_PATH = BASE_DIR / "aiwaf" / "resources" / "model.pkl"
146
- AIWAF_HONEYPOT_FIELD = "hp_field"
166
+ AIWAF_MIN_FORM_TIME = 1.0 # minimum seconds between GET and POST
147
167
  AIWAF_RATE_WINDOW = 10 # seconds
148
168
  AIWAF_RATE_MAX = 20 # max requests per window
149
169
  AIWAF_RATE_FLOOD = 10 # flood threshold
@@ -171,7 +191,7 @@ MIDDLEWARE = [
171
191
  "aiwaf.middleware.IPAndKeywordBlockMiddleware",
172
192
  "aiwaf.middleware.RateLimitMiddleware",
173
193
  "aiwaf.middleware.AIAnomalyMiddleware",
174
- "aiwaf.middleware.HoneypotMiddleware",
194
+ "aiwaf.middleware.HoneypotTimingMiddleware",
175
195
  "aiwaf.middleware.UUIDTamperMiddleware",
176
196
  # ... other middleware ...
177
197
  ]
@@ -179,24 +199,7 @@ MIDDLEWARE = [
179
199
 
180
200
  ---
181
201
 
182
- ## 🕵️ Honeypot Field (in your template)
183
-
184
- ```django
185
- {% load aiwaf_tags %}
186
-
187
- <form method="post">
188
- {% csrf_token %}
189
- {% honeypot_field %}
190
- <!-- your real fields -->
191
- </form>
192
- ```
193
-
194
- > Renders a hidden `<input name="hp_field" style="display:none">`.
195
- > Any non‑empty submission → IP blacklisted.
196
-
197
- ---
198
-
199
- ## 🔁 Running Detection & Training
202
+ ## Running Detection & Training
200
203
 
201
204
  ```bash
202
205
  python manage.py detect_and_train
@@ -219,7 +222,7 @@ python manage.py detect_and_train
219
222
  | IPAndKeywordBlockMiddleware | Blocks requests from known blacklisted IPs and Keywords |
220
223
  | RateLimitMiddleware | Enforces burst & flood thresholds |
221
224
  | AIAnomalyMiddleware | ML‑driven behavior analysis + block on anomaly |
222
- | HoneypotMiddleware | Detects bots filling hidden inputs in forms |
225
+ | HoneypotTimingMiddleware | Detects bots via GET→POST timing analysis |
223
226
  | UUIDTamperMiddleware | Blocks guessed/nonexistent UUIDs across all models in an app |
224
227
 
225
228
  ---
@@ -56,8 +56,10 @@ aiwaf/
56
56
  - **File‑Extension Probing Detection**
57
57
  Tracks repeated 404s on common extensions (e.g. `.php`, `.asp`) and blocks IPs.
58
58
 
59
- - **Honeypot Field**
60
- Hidden field for bot detection IP blacklisted on fill.
59
+ - **Timing-Based Honeypot**
60
+ Tracks GET→POST timing patterns. Blocks IPs that:
61
+ - POST directly without a preceding GET request
62
+ - Submit forms faster than `AIWAF_MIN_FORM_TIME` seconds (default: 1 second)
61
63
 
62
64
  - **UUID Tampering Protection**
63
65
  Blocks guessed or invalid UUIDs that don’t resolve to real models.
@@ -86,6 +88,24 @@ Add an IP to the exemption list using the management command:
86
88
  python manage.py add_ipexemption <ip-address> --reason "optional reason"
87
89
  ```
88
90
 
91
+ ### Resetting AI-WAF
92
+
93
+ Clear all blacklist and exemption entries:
94
+
95
+ ```bash
96
+ # Clear everything (with confirmation prompt)
97
+ python manage.py aiwaf_reset
98
+
99
+ # Clear everything without confirmation
100
+ python manage.py aiwaf_reset --confirm
101
+
102
+ # Clear only blacklist entries
103
+ python manage.py aiwaf_reset --blacklist-only
104
+
105
+ # Clear only exemption entries
106
+ python manage.py aiwaf_reset --exemptions-only
107
+ ```
108
+
89
109
  This will ensure the IP is never blocked by AI‑WAF. You can also manage exemptions via the Django admin interface.
90
110
 
91
111
  - **Daily Retraining**
@@ -122,7 +142,7 @@ AIWAF_ACCESS_LOG = "/var/log/nginx/access.log"
122
142
 
123
143
  ```python
124
144
  AIWAF_MODEL_PATH = BASE_DIR / "aiwaf" / "resources" / "model.pkl"
125
- AIWAF_HONEYPOT_FIELD = "hp_field"
145
+ AIWAF_MIN_FORM_TIME = 1.0 # minimum seconds between GET and POST
126
146
  AIWAF_RATE_WINDOW = 10 # seconds
127
147
  AIWAF_RATE_MAX = 20 # max requests per window
128
148
  AIWAF_RATE_FLOOD = 10 # flood threshold
@@ -150,7 +170,7 @@ MIDDLEWARE = [
150
170
  "aiwaf.middleware.IPAndKeywordBlockMiddleware",
151
171
  "aiwaf.middleware.RateLimitMiddleware",
152
172
  "aiwaf.middleware.AIAnomalyMiddleware",
153
- "aiwaf.middleware.HoneypotMiddleware",
173
+ "aiwaf.middleware.HoneypotTimingMiddleware",
154
174
  "aiwaf.middleware.UUIDTamperMiddleware",
155
175
  # ... other middleware ...
156
176
  ]
@@ -158,24 +178,7 @@ MIDDLEWARE = [
158
178
 
159
179
  ---
160
180
 
161
- ## 🕵️ Honeypot Field (in your template)
162
-
163
- ```django
164
- {% load aiwaf_tags %}
165
-
166
- <form method="post">
167
- {% csrf_token %}
168
- {% honeypot_field %}
169
- <!-- your real fields -->
170
- </form>
171
- ```
172
-
173
- > Renders a hidden `<input name="hp_field" style="display:none">`.
174
- > Any non‑empty submission → IP blacklisted.
175
-
176
- ---
177
-
178
- ## 🔁 Running Detection & Training
181
+ ## Running Detection & Training
179
182
 
180
183
  ```bash
181
184
  python manage.py detect_and_train
@@ -198,7 +201,7 @@ python manage.py detect_and_train
198
201
  | IPAndKeywordBlockMiddleware | Blocks requests from known blacklisted IPs and Keywords |
199
202
  | RateLimitMiddleware | Enforces burst & flood thresholds |
200
203
  | AIAnomalyMiddleware | ML‑driven behavior analysis + block on anomaly |
201
- | HoneypotMiddleware | Detects bots filling hidden inputs in forms |
204
+ | HoneypotTimingMiddleware | Detects bots via GET→POST timing analysis |
202
205
  | UUIDTamperMiddleware | Blocks guessed/nonexistent UUIDs across all models in an app |
203
206
 
204
207
  ---
@@ -0,0 +1,84 @@
1
+ from django.core.management.base import BaseCommand
2
+ from aiwaf.models import BlacklistEntry, IPExemption
3
+
4
+ class Command(BaseCommand):
5
+ help = 'Reset AI-WAF by clearing all blacklist and exemption (whitelist) entries'
6
+
7
+ def add_arguments(self, parser):
8
+ parser.add_argument(
9
+ '--blacklist-only',
10
+ action='store_true',
11
+ help='Clear only blacklist entries, keep exemptions'
12
+ )
13
+ parser.add_argument(
14
+ '--exemptions-only',
15
+ action='store_true',
16
+ help='Clear only exemption entries, keep blacklist'
17
+ )
18
+ parser.add_argument(
19
+ '--confirm',
20
+ action='store_true',
21
+ help='Skip confirmation prompt'
22
+ )
23
+
24
+ def handle(self, *args, **options):
25
+ blacklist_only = options['blacklist_only']
26
+ exemptions_only = options['exemptions_only']
27
+ confirm = options['confirm']
28
+
29
+ # Count current entries
30
+ blacklist_count = BlacklistEntry.objects.count()
31
+ exemption_count = IPExemption.objects.count()
32
+
33
+ if blacklist_only and exemptions_only:
34
+ self.stdout.write(self.style.ERROR('Cannot use both --blacklist-only and --exemptions-only flags'))
35
+ return
36
+
37
+ # Determine what to clear
38
+ if blacklist_only:
39
+ action = f"Clear {blacklist_count} blacklist entries"
40
+ clear_blacklist = True
41
+ clear_exemptions = False
42
+ elif exemptions_only:
43
+ action = f"Clear {exemption_count} exemption entries"
44
+ clear_blacklist = False
45
+ clear_exemptions = True
46
+ else:
47
+ action = f"Clear {blacklist_count} blacklist entries and {exemption_count} exemption entries"
48
+ clear_blacklist = True
49
+ clear_exemptions = True
50
+
51
+ # Show what will be cleared
52
+ self.stdout.write(f"AI-WAF Reset: {action}")
53
+
54
+ if not confirm:
55
+ response = input("Are you sure you want to proceed? [y/N]: ")
56
+ if response.lower() not in ['y', 'yes']:
57
+ self.stdout.write(self.style.WARNING('Operation cancelled'))
58
+ return
59
+
60
+ # Perform the reset
61
+ deleted_counts = {'blacklist': 0, 'exemptions': 0}
62
+
63
+ if clear_blacklist:
64
+ deleted_counts['blacklist'], _ = BlacklistEntry.objects.all().delete()
65
+
66
+ if clear_exemptions:
67
+ deleted_counts['exemptions'], _ = IPExemption.objects.all().delete()
68
+
69
+ # Report results
70
+ if clear_blacklist and clear_exemptions:
71
+ self.stdout.write(
72
+ self.style.SUCCESS(
73
+ f"✅ Reset complete: Deleted {deleted_counts['blacklist']} blacklist entries "
74
+ f"and {deleted_counts['exemptions']} exemption entries"
75
+ )
76
+ )
77
+ elif clear_blacklist:
78
+ self.stdout.write(
79
+ self.style.SUCCESS(f"✅ Blacklist cleared: Deleted {deleted_counts['blacklist']} entries")
80
+ )
81
+ elif clear_exemptions:
82
+ self.stdout.write(
83
+ self.style.SUCCESS(f"✅ Exemptions cleared: Deleted {deleted_counts['exemptions']} entries")
84
+ )
@@ -189,16 +189,37 @@ class AIAnomalyMiddleware(MiddlewareMixin):
189
189
  return response
190
190
 
191
191
 
192
- class HoneypotMiddleware(MiddlewareMixin):
193
- def process_view(self, request, view_func, view_args, view_kwargs):
192
+ class HoneypotTimingMiddleware(MiddlewareMixin):
193
+ MIN_FORM_TIME = getattr(settings, "AIWAF_MIN_FORM_TIME", 1.0) # seconds
194
+
195
+ def process_request(self, request):
194
196
  if is_exempt_path(request.path):
195
197
  return None
196
- trap = request.POST.get(getattr(settings, "AIWAF_HONEYPOT_FIELD", "hp_field"), "")
197
- if trap:
198
- ip = get_ip(request)
199
- if not is_ip_exempted(ip):
200
- BlacklistManager.block(ip, "HONEYPOT triggered")
201
- return JsonResponse({"error": "bot_detected"}, status=403)
198
+
199
+ ip = get_ip(request)
200
+ if is_ip_exempted(ip):
201
+ return None
202
+
203
+ if request.method == "GET":
204
+ # Store timestamp for this IP's GET request
205
+ cache.set(f"honeypot_get:{ip}", time.time(), timeout=300) # 5 min timeout
206
+
207
+ elif request.method == "POST":
208
+ # Check if there was a preceding GET request
209
+ get_time = cache.get(f"honeypot_get:{ip}")
210
+
211
+ if get_time is None:
212
+ # No GET request - likely bot posting directly
213
+ BlacklistManager.block(ip, "Direct POST without GET")
214
+ return JsonResponse({"error": "blocked"}, status=403)
215
+
216
+ # Check timing
217
+ time_diff = time.time() - get_time
218
+ if time_diff < self.MIN_FORM_TIME:
219
+ # Posted too quickly - likely bot
220
+ BlacklistManager.block(ip, f"Form submitted too quickly ({time_diff:.2f}s)")
221
+ return JsonResponse({"error": "blocked"}, status=403)
222
+
202
223
  return None
203
224
 
204
225
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.7.8
3
+ Version: 0.1.8.1
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -77,8 +77,10 @@ aiwaf/
77
77
  - **File‑Extension Probing Detection**
78
78
  Tracks repeated 404s on common extensions (e.g. `.php`, `.asp`) and blocks IPs.
79
79
 
80
- - **Honeypot Field**
81
- Hidden field for bot detection IP blacklisted on fill.
80
+ - **Timing-Based Honeypot**
81
+ Tracks GET→POST timing patterns. Blocks IPs that:
82
+ - POST directly without a preceding GET request
83
+ - Submit forms faster than `AIWAF_MIN_FORM_TIME` seconds (default: 1 second)
82
84
 
83
85
  - **UUID Tampering Protection**
84
86
  Blocks guessed or invalid UUIDs that don’t resolve to real models.
@@ -107,6 +109,24 @@ Add an IP to the exemption list using the management command:
107
109
  python manage.py add_ipexemption <ip-address> --reason "optional reason"
108
110
  ```
109
111
 
112
+ ### Resetting AI-WAF
113
+
114
+ Clear all blacklist and exemption entries:
115
+
116
+ ```bash
117
+ # Clear everything (with confirmation prompt)
118
+ python manage.py aiwaf_reset
119
+
120
+ # Clear everything without confirmation
121
+ python manage.py aiwaf_reset --confirm
122
+
123
+ # Clear only blacklist entries
124
+ python manage.py aiwaf_reset --blacklist-only
125
+
126
+ # Clear only exemption entries
127
+ python manage.py aiwaf_reset --exemptions-only
128
+ ```
129
+
110
130
  This will ensure the IP is never blocked by AI‑WAF. You can also manage exemptions via the Django admin interface.
111
131
 
112
132
  - **Daily Retraining**
@@ -143,7 +163,7 @@ AIWAF_ACCESS_LOG = "/var/log/nginx/access.log"
143
163
 
144
164
  ```python
145
165
  AIWAF_MODEL_PATH = BASE_DIR / "aiwaf" / "resources" / "model.pkl"
146
- AIWAF_HONEYPOT_FIELD = "hp_field"
166
+ AIWAF_MIN_FORM_TIME = 1.0 # minimum seconds between GET and POST
147
167
  AIWAF_RATE_WINDOW = 10 # seconds
148
168
  AIWAF_RATE_MAX = 20 # max requests per window
149
169
  AIWAF_RATE_FLOOD = 10 # flood threshold
@@ -171,7 +191,7 @@ MIDDLEWARE = [
171
191
  "aiwaf.middleware.IPAndKeywordBlockMiddleware",
172
192
  "aiwaf.middleware.RateLimitMiddleware",
173
193
  "aiwaf.middleware.AIAnomalyMiddleware",
174
- "aiwaf.middleware.HoneypotMiddleware",
194
+ "aiwaf.middleware.HoneypotTimingMiddleware",
175
195
  "aiwaf.middleware.UUIDTamperMiddleware",
176
196
  # ... other middleware ...
177
197
  ]
@@ -179,24 +199,7 @@ MIDDLEWARE = [
179
199
 
180
200
  ---
181
201
 
182
- ## 🕵️ Honeypot Field (in your template)
183
-
184
- ```django
185
- {% load aiwaf_tags %}
186
-
187
- <form method="post">
188
- {% csrf_token %}
189
- {% honeypot_field %}
190
- <!-- your real fields -->
191
- </form>
192
- ```
193
-
194
- > Renders a hidden `<input name="hp_field" style="display:none">`.
195
- > Any non‑empty submission → IP blacklisted.
196
-
197
- ---
198
-
199
- ## 🔁 Running Detection & Training
202
+ ## Running Detection & Training
200
203
 
201
204
  ```bash
202
205
  python manage.py detect_and_train
@@ -219,7 +222,7 @@ python manage.py detect_and_train
219
222
  | IPAndKeywordBlockMiddleware | Blocks requests from known blacklisted IPs and Keywords |
220
223
  | RateLimitMiddleware | Enforces burst & flood thresholds |
221
224
  | AIAnomalyMiddleware | ML‑driven behavior analysis + block on anomaly |
222
- | HoneypotMiddleware | Detects bots filling hidden inputs in forms |
225
+ | HoneypotTimingMiddleware | Detects bots via GET→POST timing analysis |
223
226
  | UUIDTamperMiddleware | Blocks guessed/nonexistent UUIDs across all models in an app |
224
227
 
225
228
  ---
@@ -18,6 +18,7 @@ aiwaf.egg-info/top_level.txt
18
18
  aiwaf/management/__init__.py
19
19
  aiwaf/management/commands/__init__.py
20
20
  aiwaf/management/commands/add_ipexemption.py
21
+ aiwaf/management/commands/aiwaf_reset.py
21
22
  aiwaf/management/commands/detect_and_train.py
22
23
  aiwaf/resources/model.pkl
23
24
  aiwaf/templatetags/__init__.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aiwaf"
3
- version = "0.1.7.8"
3
+ version = "0.1.8.1"
4
4
  description = "AI-powered Web Application Firewall"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.8"
@@ -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.7.8",
12
+ version="0.1.8.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",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes