From bd10f84a9bfdc131d5bf78de27182414bfb04215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 18:34:03 +0200 Subject: [PATCH] Minor patch --- data/txt/sha256sums.txt | 6 +++--- lib/core/option.py | 14 ++++++++------ lib/core/settings.py | 2 +- lib/request/keepalive.py | 27 ++++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 0fe4720d9..1c44cdae1 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -182,14 +182,14 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py 4fe3ac4c0d354d1ac42ad3f5dc1b308993588f8a249ff880d273f5031d6b52b0 lib/core/optiondict.py -98d3d61278794705c7039e40fab66a626e8d6ab765383c5379cec7a066b09301 lib/core/option.py +0235aa27d0c8cfe54180f2a003f749065d11bf167923a8189844efd45469c612 lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -47719c926f8975b57b107a698cea7ae2d43b220da38d6b9ad4055b43a560d095 lib/core/settings.py +459f3adf2d8acfe810410faea7fa5bddfc2ee0b1af284413a4a9fd1d11334047 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -219,7 +219,7 @@ a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dn 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py -d1c5e4bda94394b5bb42c3b48b41b73ecb6069c3971af2c54394c9b35c2fed6e lib/request/keepalive.py +ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py 43a7fdf64e7ba63c6b2d641c9f999a63c12ac23b43b64fedfce4e05b863de568 lib/request/pkihandler.py b90feeb16e89a844427df42373b0139eb6f6cf3c48ccec32b3e3a3f540c2451e lib/request/rangehandler.py diff --git a/lib/core/option.py b/lib/core/option.py index f7d269074..135643512 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1249,10 +1249,12 @@ def _setHTTPHandlers(): handlers.append(_urllib.request.HTTPCookieProcessor(conf.cj)) # Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html - # Note: persistent (Keep-Alive) connections are used by default; '--no-keep-alive' opts out, - # and they are automatically disabled when incompatible (HTTP(s) proxy, authentication methods, - # or chunked transfer-encoding of the request body - handled by a dedicated, non-pooling handler) - conf.keepAlive = not conf.noKeepAlive and not conf.proxy and not conf.authType and not conf.chunked + # Note: persistent (Keep-Alive) connections are used by default (including through an HTTP(s) + # proxy - the keep-alive handler pools the proxy socket for plain HTTP and the CONNECT-tunnelled + # socket per origin for HTTPS); '--no-keep-alive' opts out, and they are automatically disabled + # when incompatible (authentication methods, or chunked transfer-encoding of the request body - + # handled by a dedicated, non-pooling handler) + conf.keepAlive = not conf.noKeepAlive and not conf.authType and not conf.chunked if conf.keepAlive: # persistent connections for both HTTP and HTTPS; the keep-alive HTTPS @@ -1261,8 +1263,8 @@ def _setHTTPHandlers(): handlers.remove(httpsHandler) handlers.append(keepAliveHandler) handlers.append(keepAliveHandlerHTTPS) - elif not conf.noKeepAlive and (conf.proxy or conf.authType or conf.chunked): - reason = "an HTTP(s) proxy" if conf.proxy else ("authentication methods" if conf.authType else "chunked transfer-encoding") + elif not conf.noKeepAlive and (conf.authType or conf.chunked): + reason = "authentication methods" if conf.authType else "chunked transfer-encoding" debugMsg = "persistent (Keep-Alive) connections were disabled (incompatible with %s)" % reason logger.debug(debugMsg) diff --git a/lib/core/settings.py b/lib/core/settings.py index 0a021d5f4..fdfb62707 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.7" +VERSION = "1.10.7.8" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/request/keepalive.py b/lib/request/keepalive.py index 299a5450f..e3f192643 100644 --- a/lib/request/keepalive.py +++ b/lib/request/keepalive.py @@ -60,6 +60,22 @@ class _KeepAliveHandler(object): def _give_back(self, key, conn, count): self._pool.conns[key] = [conn, count, time.time()] + @staticmethod + def _takeTunnelHeaders(req): + """ + Pops the Proxy-Authorization header off L{req} (returning it as a dict) so it rides on the + CONNECT request only and is never forwarded through the tunnel to the origin server, mirroring + the stock C{urllib.request.AbstractHTTPHandler.do_open} tunnel setup + """ + + result = {} + for store in (getattr(req, "unredirected_hdrs", None), getattr(req, "headers", None)): + if store: + for name in list(store): + if name.lower() == "proxy-authorization": + result[name] = store.pop(name) + return result + def do_open(self, req): # Note: 'selector'/'host' attributes on Python 3 (Request.get_host() was deprecated since # 3.3 and removed in 3.12); the get_*() fallbacks are only reachable under Python 2 @@ -68,7 +84,14 @@ class _KeepAliveHandler(object): if not host: raise _urllib.error.URLError("no host given") - key = "%s://%s" % (self._scheme, host) + # When routed through an HTTP(s) proxy, ProxyHandler has already rewritten the request: for a + # plain-HTTP target 'host' is the proxy and the selector is absolute; for an HTTPS target + # '_tunnel_host' holds the origin reached via a CONNECT tunnel. Pool by the tunnel origin when + # tunneling (each origin needs its own tunnelled socket) and by 'host' otherwise (one HTTP-proxy + # socket serves many origins, and a direct connection is keyed by its own host exactly as before). + tunnelHost = getattr(req, "_tunnel_host", None) + tunnelHeaders = self._takeTunnelHeaders(req) if tunnelHost else None + key = "%s://%s" % (self._scheme, tunnelHost or host) conn, count = self._take(key) reused = conn is not None @@ -93,6 +116,8 @@ class _KeepAliveHandler(object): if conn is None: conn = self._get_connection(host) + if tunnelHost: + conn.set_tunnel(tunnelHost, headers=tunnelHeaders or {}) count = 0 self._send_request(conn, req) response = conn.getresponse()