Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package wafw00f for openSUSE:Factory checked in at 2026-06-10 16:11:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wafw00f (Old) and /work/SRC/openSUSE:Factory/.wafw00f.new.2375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wafw00f" Wed Jun 10 16:11:41 2026 rev:4 rq:1358341 version:2.4.2 Changes: -------- --- /work/SRC/openSUSE:Factory/wafw00f/wafw00f.changes 2026-01-07 16:03:28.052243749 +0100 +++ /work/SRC/openSUSE:Factory/.wafw00f.new.2375/wafw00f.changes 2026-06-10 16:17:05.560241323 +0200 @@ -1,0 +2,52 @@ +Tue Jun 2 13:08:39 UTC 2026 - [email protected] + +- Update to version 2.4.2: + * Removes setup.py to fix tool installations when building locally. + * Updated the latest supported versions of Python (≥3.10) + * New WAF signature updates: + - Vercel WAF + - Reflected Networks WAF + * Improvements to existing signatures: + - Tencent WAF + +- Update to version 2.4.1: + * Fix timeout enforcement during response body reading to properly + handle slow streaming servers. + * Timeout enforcement: The --timeout parameter is now properly + enforced during response body reading, not just during connection + establishment. This fixes the issue where slow-streaming servers + could cause scans to take over 2 minutes instead of respecting + the user-specified timeout. + * Track elapsed time during chunk reading loop + * Break out of reading loop if timeout is exceeded during reading + * Add test documenting timeout enforcement behavior + +- Update to version 2.4.0: + * New WAF detections + - Anubis (Techaro) + - Scutum (Secure Sky Technology) + - 360PanYun (360 Technologies) + - ThreatX (A10 Networks) + - Link11 WAAP + * Improvements + - Fastly detection improvements (tighter regex for X-Served-By) + - Added pytest test framework with 45 tests + - Added pyproject.toml for modern Python packaging + - Removed pluginbase dependency (use stdlib importlib) + * Fixes + - Fixed infinite hang on streaming responses (#246) + - Improved -t option help text (#243) + * Other + - Updated copyright years to 2026 + - Updated Python requirement to 3.8+ + +- Add fix-request-path.patch based on commit af3eca1: + Noticed that path attacks like LFI were being ignored. Changed + the way requests were done to ensure that the path is not normalized + by creating a prepared request and overwrite the url. +- Use source from github to get complete tests +- Switch to wheel/pip build +- Add %check/%pytest +- Clean up spec file + +------------------------------------------------------------------- Old: ---- wafw00f-2.3.2.tar.gz New: ---- fix-request-path.patch wafw00f-2.4.2.tar.gz ----------(New B)---------- New: - Add fix-request-path.patch based on commit af3eca1: Noticed that path attacks like LFI were being ignored. Changed ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wafw00f.spec ++++++ --- /var/tmp/diff_new_pack.ZnMUWu/_old 2026-06-10 16:17:06.748290557 +0200 +++ /var/tmp/diff_new_pack.ZnMUWu/_new 2026-06-10 16:17:06.756290889 +0200 @@ -16,27 +16,34 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} +%bcond_without libalternatives + Name: wafw00f -Version: 2.3.2 +Version: 2.4.2 Release: 0 Summary: The Web Application Firewall Detection and Fingerprinting Toolkit License: BSD-3-Clause URL: https://github.com/enablesecurity/wafw00f -Source: https://files.pythonhosted.org/packages/source/w/wafw00f/wafw00f-%{version}.tar.gz +#Source0: https://files.pythonhosted.org/packages/source/w/wafw00f/wafw00f-%%{version}.tar.gz +# use source from github to get complete tests +Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz +# PATCH-FIX-UPSTREAM fix-request-path.patch -- based on commit af3eca1 +Patch0: fix-request-path.patch +BuildRequires: %{python_module base >= 3.10} +BuildRequires: %{python_module pip} +BuildRequires: %{python_module requests} BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module wheel} +BuildRequires: alts +BuildRequires: fdupes BuildRequires: python-rpm-macros # SECTION test requirements -BuildRequires: %{python_module pluginbase} -BuildRequires: %{python_module requests} -BuildRequires: %{python_module requests} +BuildRequires: %{python_module pytest} +BuildRequires: %{python_module pytest-mock} +BuildRequires: %{python_module responses} # /SECTION -BuildRequires: fdupes -Requires: python-pluginbase -Requires: python-requests +Requires: alts Requires: python-requests -Suggests: python-prospector -Suggests: python-Sphinx BuildArch: noarch %python_subpackages @@ -44,17 +51,25 @@ The Web Application Firewall Detection and Fingerprinting Toolkit. %prep -%setup -q -n wafw00f-%{version} +%autosetup -p1 +# fix non-executable-script find . -iname "*.py" -exec sed -i '1{/^#!/ d}' {} \; %build -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install %python_clone -a %{buildroot}%{_bindir}/wafw00f +%python_expand %python3_fix_shebang_path %{buildroot}%{$python_sitelib}/wafw00f/bin/wafw00f %python_expand %fdupes %{buildroot}%{$python_sitelib} +%check +%pytest + +%pre +%python_libalternatives_reset_alternative wafw00f + %post %python_install_alternative wafw00f @@ -65,5 +80,6 @@ %doc README.md %license LICENSE %python_alternative %{_bindir}/wafw00f -%{python_sitelib}/* +%{python_sitelib}/wafw00f +%{python_sitelib}/wafw00f-%{version}.dist-info ++++++ fix-request-path.patch ++++++ >From 4f7b422fc2cfd8305984c21a6adbb53be091ef8d Mon Sep 17 00:00:00 2001 From: Diogo Castilho <[email protected]> Date: Wed, 25 Mar 2026 14:26:26 +0000 Subject: [PATCH] Fix request path --- tests/test_evillib.py | 22 ++++++++++++++++++++++ wafw00f/lib/evillib.py | 25 +++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/tests/test_evillib.py b/tests/test_evillib.py index 52b0bcdf..4d7ef4b7 100644 --- a/tests/test_evillib.py +++ b/tests/test_evillib.py @@ -146,3 +146,25 @@ def test_timeout_attribute_used(self): # Verify the engine has timeout configured assert engine.timeout == 5 assert resp is not None + + +class TestPathPreservation: + """Tests that request paths are not normalized.""" + + @responses.activate + def test_path_traversal_not_normalized(self): + """Test path traversal sequences are preserved.""" + responses.add(responses.GET, 'https://example.com/../../etc/passwd', status=200) + engine = waftoolsengine(target='https://example.com') + engine.Request(path='../../etc/passwd') + assert '../../etc/passwd' in responses.calls[0].request.url + + @responses.activate + def test_path_traversal_with_params(self): + """Test path traversal is preserved when query params are present.""" + responses.add(responses.GET, 'https://example.com/../../etc/passwd', status=200) + engine = waftoolsengine(target='https://example.com') + engine.Request(path='../../etc/passwd', params={'key': 'val'}) + url = responses.calls[0].request.url + assert '../../etc/passwd' in url + assert 'key=val' in url diff --git a/wafw00f/lib/evillib.py b/wafw00f/lib/evillib.py index 37276866..780cee77 100755 --- a/wafw00f/lib/evillib.py +++ b/wafw00f/lib/evillib.py @@ -7,6 +7,7 @@ import time import logging from copy import copy +from urllib.parse import urlparse import requests import urllib3 @@ -57,8 +58,28 @@ def Request(self, headers=None, path=None, params={}, delay=0): if not headers: h = self.headers else: h = headers - req = requests.get(self.target, proxies=self.proxies, headers=h, timeout=self.timeout, - allow_redirects=self.allowredir, params=params, verify=False, stream=True) + + # Create the url manually to avoid path normalization + url = self.target if path is None else self.target.rstrip('/') + '/' + path.lstrip('/') + prepared = requests.Request('GET', url, headers=h, + params=params or {}).prepare() + + parsed_url = urlparse(prepared.url) + + # Ensuring trailing slash does not disappear + trailing_slash = parsed_url.path.endswith('/') + if trailing_slash and not url.endswith('/'): + url += '/' + + # Preserve the original path (e.g. ../../etc/passwd) + if params: + prepared.url = url + '?' + parsed_url.query + else: + prepared.url = url + + req = requests.Session().send(prepared, proxies=self.proxies, timeout=self.timeout, + allow_redirects=self.allowredir, verify=False, stream=True) + # Read only up to MAX_RESPONSE_SIZE to avoid hanging on streaming responses # (e.g., audio streams) - see issue #246 # Also enforce timeout during reading to handle slow streaming servers ++++++ wafw00f-2.3.2.tar.gz -> wafw00f-2.4.2.tar.gz ++++++ ++++ 4986 lines of diff (skipped)
