aiwaf 0.1.8.4__py3-none-any.whl → 0.1.8.5__py3-none-any.whl

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/middleware.py CHANGED
@@ -219,7 +219,8 @@ class HoneypotTimingMiddleware(MiddlewareMixin):
219
219
  return None
220
220
 
221
221
  if request.method == "GET":
222
- # Store timestamp for this IP's GET request
222
+ # Store timestamp for this IP's GET request
223
+ # Use a general key for the IP, not path-specific
223
224
  cache.set(f"honeypot_get:{ip}", time.time(), timeout=300) # 5 min timeout
224
225
 
225
226
  elif request.method == "POST":
@@ -228,15 +229,26 @@ class HoneypotTimingMiddleware(MiddlewareMixin):
228
229
 
229
230
  if get_time is None:
230
231
  # No GET request - likely bot posting directly
231
- BlacklistManager.block(ip, "Direct POST without GET")
232
- return JsonResponse({"error": "blocked"}, status=403)
233
-
234
- # Check timing
235
- time_diff = time.time() - get_time
236
- if time_diff < self.MIN_FORM_TIME:
237
- # Posted too quickly - likely bot
238
- BlacklistManager.block(ip, f"Form submitted too quickly ({time_diff:.2f}s)")
239
- return JsonResponse({"error": "blocked"}, status=403)
232
+ # But be more lenient for login paths since users might bookmark them
233
+ if not any(request.path.lower().startswith(login_path) for login_path in [
234
+ "/admin/login/", "/login/", "/accounts/login/", "/auth/login/", "/signin/"
235
+ ]):
236
+ BlacklistManager.block(ip, "Direct POST without GET")
237
+ return JsonResponse({"error": "blocked"}, status=403)
238
+ else:
239
+ # Check timing - be more lenient for login paths
240
+ time_diff = time.time() - get_time
241
+ min_time = self.MIN_FORM_TIME
242
+
243
+ # Use shorter time threshold for login paths (users can login quickly)
244
+ if any(request.path.lower().startswith(login_path) for login_path in [
245
+ "/admin/login/", "/login/", "/accounts/login/", "/auth/login/", "/signin/"
246
+ ]):
247
+ min_time = 0.1 # Very short threshold for login forms
248
+
249
+ if time_diff < min_time:
250
+ BlacklistManager.block(ip, f"Form submitted too quickly ({time_diff:.2f}s)")
251
+ return JsonResponse({"error": "blocked"}, status=403)
240
252
 
241
253
  return None
242
254
 
aiwaf/trainer.py CHANGED
@@ -203,13 +203,48 @@ def train() -> None:
203
203
  os.makedirs(os.path.dirname(MODEL_PATH), exist_ok=True)
204
204
  joblib.dump(model, MODEL_PATH)
205
205
  print(f"Model trained on {len(X)} samples → {MODEL_PATH}")
206
+
207
+ # Check for anomalies and intelligently decide which IPs to block
206
208
  preds = model.predict(X)
207
209
  anomalous_ips = set(df.loc[preds == -1, "ip"])
208
- for ip in anomalous_ips:
209
- BlacklistEntry.objects.get_or_create(
210
- ip_address=ip,
211
- defaults={"reason": "Anomalous behavior"}
212
- )
210
+
211
+ if anomalous_ips:
212
+ print(f"⚠️ Detected {len(anomalous_ips)} potentially anomalous IPs during training")
213
+
214
+ blocked_count = 0
215
+ for ip in anomalous_ips:
216
+ # Skip if IP is exempted
217
+ if IPExemption.objects.filter(ip_address=ip).exists():
218
+ continue
219
+
220
+ # Get this IP's behavior from the data
221
+ ip_data = df[df["ip"] == ip]
222
+
223
+ # Criteria to determine if this is likely a legitimate user vs threat:
224
+ avg_kw_hits = ip_data["kw_hits"].mean()
225
+ max_404s = ip_data["total_404"].max()
226
+ avg_burst = ip_data["burst_count"].mean()
227
+ total_requests = len(ip_data)
228
+
229
+ # Don't block if it looks like legitimate behavior:
230
+ if (
231
+ avg_kw_hits < 2 and # Not hitting many malicious keywords
232
+ max_404s < 10 and # Not excessive 404s
233
+ avg_burst < 15 and # Not excessive burst activity
234
+ total_requests < 100 # Not excessive total requests
235
+ ):
236
+ print(f" - {ip}: Anomalous but looks legitimate (kw:{avg_kw_hits:.1f}, 404s:{max_404s}, burst:{avg_burst:.1f}) - NOT blocking")
237
+ continue
238
+
239
+ # Block if it shows clear signs of malicious behavior
240
+ BlacklistEntry.objects.get_or_create(
241
+ ip_address=ip,
242
+ defaults={"reason": f"AI anomaly + suspicious patterns (kw:{avg_kw_hits:.1f}, 404s:{max_404s}, burst:{avg_burst:.1f})"}
243
+ )
244
+ blocked_count += 1
245
+ print(f" - {ip}: Blocked for suspicious behavior (kw:{avg_kw_hits:.1f}, 404s:{max_404s}, burst:{avg_burst:.1f})")
246
+
247
+ print(f" → Blocked {blocked_count}/{len(anomalous_ips)} anomalous IPs (others looked legitimate)")
213
248
 
214
249
  tokens = Counter()
215
250
  for r in parsed:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.8.4
3
+ Version: 0.1.8.5
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -1,10 +1,10 @@
1
1
  aiwaf/__init__.py,sha256=nQFpJ1YpX48snzLjEQCf8zD2YNh8v0b_kPTrXx8uBYc,46
2
2
  aiwaf/apps.py,sha256=nCez-Ptlv2kaEk5HenA8b1pATz1VfhrHP1344gwcY1A,142
3
3
  aiwaf/blacklist_manager.py,sha256=sM6uTH7zD6MOPGb0kzqV2aFut2vxKgft_UVeRJr7klw,392
4
- aiwaf/middleware.py,sha256=3zFW0hGPpNti2_6Vbamw8m8YiqcJ2jC5sygWNxJPsMU,9670
4
+ aiwaf/middleware.py,sha256=GmN9R6z1wx1g4coMoixGK_b3i4dwI5z0xBAIu4I7CoQ,10477
5
5
  aiwaf/models.py,sha256=XaG1pd_oZu3y-fw66u4wblGlWcUY9gvsTNKGD0kQk7Y,1672
6
6
  aiwaf/storage.py,sha256=bxCILzzvA1-q6nwclRE8WrfoRhe25H4VrsQDf0hl_lY,1903
7
- aiwaf/trainer.py,sha256=IUPCGVe0RT6sRHecBeNZuKop2d6APzXlvv3nirgKQLI,7319
7
+ aiwaf/trainer.py,sha256=eJOHuJgIyqUIqmbYwnMWoR4fQQ8miTn64ASXMmShgI8,9120
8
8
  aiwaf/utils.py,sha256=RkEUWhhHy6tOk7V0UYv3cN4xhOR_7aBy9bjhwuV2cdA,1436
9
9
  aiwaf/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  aiwaf/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -14,8 +14,8 @@ aiwaf/management/commands/detect_and_train.py,sha256=-o-LZ7QZ5GeJPCekryox1DGXKMm
14
14
  aiwaf/resources/model.pkl,sha256=5t6h9BX8yoh2xct85MXOO60jdlWyg1APskUOW0jZE1Y,1288265
15
15
  aiwaf/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  aiwaf/templatetags/aiwaf_tags.py,sha256=XXfb7Tl4DjU3Sc40GbqdaqOEtKTUKELBEk58u83wBNw,357
17
- aiwaf-0.1.8.4.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
18
- aiwaf-0.1.8.4.dist-info/METADATA,sha256=abO7KBH2-WR5UDKt_bawhvXohcIToLXKQm_J33uwjRY,7435
19
- aiwaf-0.1.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- aiwaf-0.1.8.4.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
21
- aiwaf-0.1.8.4.dist-info/RECORD,,
17
+ aiwaf-0.1.8.5.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
18
+ aiwaf-0.1.8.5.dist-info/METADATA,sha256=ef023TmhChIqMkNwTgEsyPODvDs44q9SXmQCYjxzoBs,7435
19
+ aiwaf-0.1.8.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ aiwaf-0.1.8.5.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
21
+ aiwaf-0.1.8.5.dist-info/RECORD,,