aiwaf 0.1.9.2.3__py3-none-any.whl → 0.1.9.2.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/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  default_app_config = "aiwaf.apps.AiwafConfig"
2
2
 
3
- __version__ = "0.1.9.2.3"
3
+ __version__ = "0.1.9.2.5"
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
@@ -179,17 +179,26 @@ class IPAndKeywordBlockMiddleware:
179
179
  def extract_from_pattern(pattern, prefix=""):
180
180
  try:
181
181
  if isinstance(pattern, URLResolver):
182
- # Handle include() patterns
182
+ # Handle include() patterns - be permissive for URL prefixes that route to apps
183
183
  namespace = getattr(pattern, 'namespace', None)
184
184
  if namespace:
185
185
  for segment in re.split(r'[._-]', namespace.lower()):
186
186
  if len(segment) > 2:
187
187
  keywords.add(segment)
188
188
 
189
- # Extract from the pattern itself
189
+ # Extract from the pattern itself - improved logic for include() patterns
190
190
  pattern_str = str(pattern.pattern)
191
- for segment in re.findall(r'([a-zA-Z]\w{2,})', pattern_str):
192
- keywords.add(segment.lower())
191
+ # Get literal path segments (not regex parts)
192
+ literal_parts = re.findall(r'([a-zA-Z][a-zA-Z0-9_-]*)', pattern_str)
193
+
194
+ # For include() patterns, be more permissive since they're routing to existing apps
195
+ # The key insight: if someone includes an app's URLs, the prefix is legitimate by design
196
+ for part in literal_parts:
197
+ if len(part) > 2:
198
+ part_lower = part.lower()
199
+ # For URLResolver (include patterns), be more permissive
200
+ # These are URL prefixes that route to actual app functionality
201
+ keywords.add(part_lower)
193
202
 
194
203
  # Recurse into nested patterns
195
204
  for nested_pattern in pattern.url_patterns:
@@ -578,10 +587,24 @@ class AIAnomalyMiddleware(MiddlewareMixin):
578
587
  data = [d for d in data if now - d[0] < self.WINDOW]
579
588
  cache.set(key, data, timeout=self.WINDOW)
580
589
 
581
- keyword_store = get_keyword_store()
582
- for seg in re.split(r"\W+", request.path.lower()):
583
- if len(seg) > 3:
584
- keyword_store.add_keyword(seg)
590
+ data.append((now, request.path, response.status_code, resp_time))
591
+ data = [d for d in data if now - d[0] < self.WINDOW]
592
+ cache.set(key, data, timeout=self.WINDOW)
593
+
594
+ # Only learn keywords from error responses and non-existent paths
595
+ # This prevents learning legitimate keywords from successful requests
596
+ if (response.status_code >= 400 and not known_path and not is_exempt_path(request.path)):
597
+ keyword_store = get_keyword_store()
598
+ # Get legitimate keywords to avoid learning them
599
+ from .trainer import get_legitimate_keywords
600
+ legitimate_keywords = get_legitimate_keywords()
601
+
602
+ for seg in re.split(r"\W+", request.path.lower()):
603
+ if (len(seg) > 3 and
604
+ seg not in STATIC_KW and # Don't re-learn static keywords
605
+ seg not in legitimate_keywords and # Don't learn legitimate keywords
606
+ self._is_malicious_context(request, seg)): # Only learn in malicious context
607
+ keyword_store.add_keyword(seg)
585
608
 
586
609
  return response
587
610
 
aiwaf/trainer.py CHANGED
@@ -198,20 +198,37 @@ def _extract_django_route_keywords() -> set:
198
198
  def extract_from_pattern(pattern, prefix=""):
199
199
  try:
200
200
  if isinstance(pattern, URLResolver):
201
- # Handle include() patterns
201
+ # Handle include() patterns - check if they include legitimate apps
202
202
  namespace = getattr(pattern, 'namespace', None)
203
203
  if namespace:
204
204
  for segment in re.split(r'[._-]', namespace.lower()):
205
205
  if len(segment) > 2:
206
206
  keywords.add(segment)
207
207
 
208
- # Extract from the pattern itself - more comprehensive
208
+ # Extract from the pattern itself - improved logic for include() patterns
209
209
  pattern_str = str(pattern.pattern)
210
210
  # Get literal path segments (not regex parts)
211
211
  literal_parts = re.findall(r'([a-zA-Z][a-zA-Z0-9_-]*)', pattern_str)
212
+
213
+ # Get list of actual Django app names to validate against
214
+ app_names = set()
215
+ for app_config in apps.get_app_configs():
216
+ app_parts = app_config.name.lower().replace('-', '_').split('.')
217
+ for part in app_parts:
218
+ for segment in re.split(r'[._-]', part):
219
+ if len(segment) > 2:
220
+ app_names.add(segment)
221
+ if app_config.label:
222
+ app_names.add(app_config.label.lower())
223
+
224
+ # For include() patterns, be more permissive since they're routing to existing apps
225
+ # The key insight: if someone includes an app's URLs, the prefix is legitimate by design
212
226
  for part in literal_parts:
213
227
  if len(part) > 2:
214
- keywords.add(part.lower())
228
+ part_lower = part.lower()
229
+ # For URLResolver (include patterns), be more permissive
230
+ # These are URL prefixes that route to actual app functionality
231
+ keywords.add(part_lower)
215
232
 
216
233
  # Recurse into nested patterns
217
234
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.9.2.3
3
+ Version: 0.1.9.2.5
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -1,12 +1,12 @@
1
- aiwaf/__init__.py,sha256=oJ3sGVirmahdoT5DpCTp_liJkyeRv9FllrYYKRkThnU,220
1
+ aiwaf/__init__.py,sha256=0cr5WYpPFupra8Xms3_swtRbJDdZ3pYEjAnRaRSguIA,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=-w_uOaZgakFoJkvmJUB7atqcYQr3nSd9HbSKlP8_178,30370
5
+ aiwaf/middleware.py,sha256=KW982p1eZ3hJYiR0lidomImkB5_J9uhfgCLzsMt53MI,32048
6
6
  aiwaf/middleware_logger.py,sha256=LWZVDAnjh6CGESirA8eMbhGgJKB7lVDGRQqVroH95Lo,4742
7
7
  aiwaf/models.py,sha256=vQxgY19BDVMjoO903UNrTZC1pNoLltMU6wbyWPoAEns,2719
8
8
  aiwaf/storage.py,sha256=5ImrZMRn3u7HNsPH0fDjWhDrD2tgG2IHVnOXtLz0fk4,10253
9
- aiwaf/trainer.py,sha256=E9jNPq1EHJkKpX1loZrUd2BDBAvH79w_Ltbdb1fsc0Q,25259
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
12
12
  aiwaf/management/commands/__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.3.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
33
- aiwaf-0.1.9.2.3.dist-info/METADATA,sha256=nLqJ4rOXO6IFxBr_0EBdnlYRk824Uii9KYLnsObfJx0,26824
34
- aiwaf-0.1.9.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- aiwaf-0.1.9.2.3.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
36
- aiwaf-0.1.9.2.3.dist-info/RECORD,,
32
+ aiwaf-0.1.9.2.5.dist-info/licenses/LICENSE,sha256=Ir8PX4dxgAcdB0wqNPIkw84fzIIRKE75NoUil9RX0QU,1069
33
+ aiwaf-0.1.9.2.5.dist-info/METADATA,sha256=YCEXlU9C4qclQ4VB_Tz5Wbn1eGk3DzREmyl83JaZuik,26824
34
+ aiwaf-0.1.9.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ aiwaf-0.1.9.2.5.dist-info/top_level.txt,sha256=kU6EyjobT6UPCxuWpI_BvcHDG0I2tMgKaPlWzVxe2xI,6
36
+ aiwaf-0.1.9.2.5.dist-info/RECORD,,