aiwaf 0.1.9.2.6__py3-none-any.whl → 0.1.9.2.8__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/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  default_app_config = "aiwaf.apps.AiwafConfig"
2
2
 
3
- __version__ = "0.1.9.2.6"
3
+ __version__ = "0.1.9.2.8"
4
4
 
5
5
  # Note: Middleware classes are available from aiwaf.middleware
6
6
  # Import them only when needed to avoid circular imports during Django app loading
aiwaf/middleware.py CHANGED
@@ -85,6 +85,7 @@ class IPAndKeywordBlockMiddleware:
85
85
  self.safe_prefixes = self._collect_safe_prefixes()
86
86
  self.exempt_keywords = self._get_exempt_keywords()
87
87
  self.legitimate_path_keywords = self._get_legitimate_path_keywords()
88
+ self.malicious_keywords = set(STATIC_KW) # Initialize malicious keywords
88
89
 
89
90
  def _get_exempt_keywords(self):
90
91
  """Get keywords that should be exempt from blocking"""
@@ -439,6 +440,7 @@ class AIAnomalyMiddleware(MiddlewareMixin):
439
440
  super().__init__(get_response)
440
441
  # Use the safely loaded global MODEL instead of loading again
441
442
  self.model = MODEL
443
+ self.malicious_keywords = set(STATIC_KW) # Initialize malicious keywords
442
444
 
443
445
  def _is_malicious_context(self, request, keyword):
444
446
  """
aiwaf/storage.py CHANGED
@@ -2,10 +2,17 @@ import numpy as np
2
2
  import pandas as pd
3
3
  from django.conf import settings
4
4
  from django.utils import timezone
5
+ import os
6
+ import json
7
+ from collections import defaultdict
5
8
 
6
9
  # Defer model imports to avoid AppRegistryNotReady during Django app loading
7
10
  FeatureSample = BlacklistEntry = IPExemption = DynamicKeyword = None
8
11
 
12
+ # Fallback storage for when Django models are unavailable
13
+ _fallback_keywords = defaultdict(int)
14
+ _fallback_storage_path = os.path.join(os.path.dirname(__file__), 'fallback_keywords.json')
15
+
9
16
  def _import_models():
10
17
  """Import Django models only when needed and apps are ready."""
11
18
  global FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
@@ -15,9 +22,24 @@ def _import_models():
15
22
 
16
23
  try:
17
24
  from django.apps import apps
18
- if apps.ready and apps.is_installed('aiwaf'):
19
- from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
20
- except (ImportError, RuntimeError, Exception):
25
+ if apps.ready:
26
+ # Try multiple ways to import models
27
+ try:
28
+ # First try: direct import (most reliable)
29
+ from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
30
+ except ImportError:
31
+ # Second try: check if aiwaf app is installed under different name
32
+ for app_config in apps.get_app_configs():
33
+ if 'aiwaf' in app_config.name.lower() or 'aiwaf' in app_config.label.lower():
34
+ try:
35
+ from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
36
+ break
37
+ except ImportError:
38
+ continue
39
+ except (ImportError, RuntimeError, Exception) as e:
40
+ # Log the error for debugging but don't fail silently
41
+ import sys
42
+ print(f"Warning: Could not import AIWAF models: {e}", file=sys.stderr)
21
43
  # Keep models as None if can't import
22
44
  pass
23
45
 
@@ -242,11 +264,40 @@ class ModelExemptionStore:
242
264
  return 0
243
265
 
244
266
  class ModelKeywordStore:
267
+ @staticmethod
268
+ def _load_fallback_keywords():
269
+ """Load keywords from fallback JSON file"""
270
+ global _fallback_keywords
271
+ try:
272
+ if os.path.exists(_fallback_storage_path):
273
+ with open(_fallback_storage_path, 'r') as f:
274
+ data = json.load(f)
275
+ _fallback_keywords = defaultdict(int, data)
276
+ except Exception as e:
277
+ import sys
278
+ print(f"Warning: Could not load fallback keywords: {e}", file=sys.stderr)
279
+
280
+ @staticmethod
281
+ def _save_fallback_keywords():
282
+ """Save keywords to fallback JSON file"""
283
+ try:
284
+ with open(_fallback_storage_path, 'w') as f:
285
+ json.dump(dict(_fallback_keywords), f, indent=2)
286
+ except Exception as e:
287
+ import sys
288
+ print(f"Warning: Could not save fallback keywords: {e}", file=sys.stderr)
289
+
245
290
  @staticmethod
246
291
  def add_keyword(keyword, count=1):
247
292
  """Add a keyword to the dynamic keyword list"""
248
293
  _import_models()
249
294
  if DynamicKeyword is None:
295
+ # Use fallback storage
296
+ ModelKeywordStore._load_fallback_keywords()
297
+ _fallback_keywords[keyword] += count
298
+ ModelKeywordStore._save_fallback_keywords()
299
+ import sys
300
+ print(f"Warning: Using fallback storage for keyword '{keyword}' - Django models not available.", file=sys.stderr)
250
301
  return
251
302
  try:
252
303
  obj, created = DynamicKeyword.objects.get_or_create(keyword=keyword)
@@ -257,7 +308,12 @@ class ModelKeywordStore:
257
308
  obj.count = count
258
309
  obj.save()
259
310
  except Exception as e:
260
- print(f"Error adding keyword {keyword}: {e}")
311
+ # Fallback to file storage on database error
312
+ ModelKeywordStore._load_fallback_keywords()
313
+ _fallback_keywords[keyword] += count
314
+ ModelKeywordStore._save_fallback_keywords()
315
+ import sys
316
+ print(f"Database error adding keyword {keyword}, using fallback storage: {e}", file=sys.stderr)
261
317
 
262
318
  @staticmethod
263
319
  def remove_keyword(keyword):
@@ -275,14 +331,22 @@ class ModelKeywordStore:
275
331
  """Get top N keywords by count"""
276
332
  _import_models()
277
333
  if DynamicKeyword is None:
278
- return []
334
+ # Use fallback storage
335
+ ModelKeywordStore._load_fallback_keywords()
336
+ sorted_keywords = sorted(_fallback_keywords.items(), key=lambda x: x[1], reverse=True)
337
+ return [keyword for keyword, count in sorted_keywords[:n]]
279
338
  try:
280
339
  return list(
281
340
  DynamicKeyword.objects.order_by('-count')[:n]
282
341
  .values_list('keyword', flat=True)
283
342
  )
284
- except Exception:
285
- return []
343
+ except Exception as e:
344
+ # Fallback to file storage on database error
345
+ ModelKeywordStore._load_fallback_keywords()
346
+ sorted_keywords = sorted(_fallback_keywords.items(), key=lambda x: x[1], reverse=True)
347
+ import sys
348
+ print(f"Database error getting top keywords, using fallback storage: {e}", file=sys.stderr)
349
+ return [keyword for keyword, count in sorted_keywords[:n]]
286
350
 
287
351
  @staticmethod
288
352
  def get_all_keywords():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.9.2.6
3
+ Version: 0.1.9.2.8
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -1,11 +1,11 @@
1
- aiwaf/__init__.py,sha256=vgc-dT-AtR3_k84Wpmujg4ZRwl6EuU7IR2_KW2B0tBU,220
1
+ aiwaf/__init__.py,sha256=xnE1gh2l0bta59Oy61sIlrsVe7BB_dCE1qFGBjvFTsg,220
2
2
  aiwaf/apps.py,sha256=nCez-Ptlv2kaEk5HenA8b1pATz1VfhrHP1344gwcY1A,142
3
3
  aiwaf/blacklist_manager.py,sha256=LYCeKFB-7e_C6Bg2WeFJWFIIQlrfRMPuGp30ivrnhQY,1196
4
4
  aiwaf/decorators.py,sha256=IUKOdM_gdroffImRZep1g1wT6gNqD10zGwcp28hsJCs,825
5
- aiwaf/middleware.py,sha256=cpxOI6W45A6qRa9Ulk1StqCTSJjCoBx387FegZB0iMA,31889
5
+ aiwaf/middleware.py,sha256=ThR0Bxw_VbGcOsRMIXMmQ5OMOIAy19z4SulsK7rZ_NM,32053
6
6
  aiwaf/middleware_logger.py,sha256=LWZVDAnjh6CGESirA8eMbhGgJKB7lVDGRQqVroH95Lo,4742
7
7
  aiwaf/models.py,sha256=vQxgY19BDVMjoO903UNrTZC1pNoLltMU6wbyWPoAEns,2719
8
- aiwaf/storage.py,sha256=5ImrZMRn3u7HNsPH0fDjWhDrD2tgG2IHVnOXtLz0fk4,10253
8
+ aiwaf/storage.py,sha256=3lnmbML-gFxpPpVl1Huz_cqE6Qt2LMIrYoeHFnFyAz0,13452
9
9
  aiwaf/trainer.py,sha256=hswkopOnEQHNkSn79AIk-OWw6zatP2EDhsBBEHQeFYw,26410
10
10
  aiwaf/utils.py,sha256=BJk5vJCYdGPl_4QQiknjhCbkzv5HZCXgFcBJDMJpHok,3390
11
11
  aiwaf/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -29,8 +29,8 @@ aiwaf/management/commands/test_exemption_fix.py,sha256=ngyGaHUCmQQ6y--6j4q1viZJt
29
29
  aiwaf/resources/model.pkl,sha256=5t6h9BX8yoh2xct85MXOO60jdlWyg1APskUOW0jZE1Y,1288265
30
30
  aiwaf/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  aiwaf/templatetags/aiwaf_tags.py,sha256=XXfb7Tl4DjU3Sc40GbqdaqOEtKTUKELBEk58u83wBNw,357
32
- aiwaf-0.1.9.2.6.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
33
- aiwaf-0.1.9.2.6.dist-info/METADATA,sha256=iaCG43PeSHGu16Jawzelh5Qi0PoGysvi_BYfWFIcvbA,26824
34
- aiwaf-0.1.9.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- aiwaf-0.1.9.2.6.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
36
- aiwaf-0.1.9.2.6.dist-info/RECORD,,
32
+ aiwaf-0.1.9.2.8.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
33
+ aiwaf-0.1.9.2.8.dist-info/METADATA,sha256=kLAzz-5iApYmZhxQv27t7i1xi17eAj6GL-r8s6qOYzo,26824
34
+ aiwaf-0.1.9.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ aiwaf-0.1.9.2.8.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
36
+ aiwaf-0.1.9.2.8.dist-info/RECORD,,