Skip to content

Commit 6319063

Browse files
committed
fix: prevent proxy timeout by removing duplicate headers in config file
When using request file mode (-r), headers were being passed through both the request file and the options.headers config option, causing: - Connection: keep-alive bypassing parseRequestFile filtering, exhausting proxy pool - Content-Length being fixed at original value, mismatching injected body size - Other intentionally-skipped headers (Proxy-Connection etc.) being re-added Now headers are only passed via the request file, matching command-line behavior.
1 parent cdff8f6 commit 6319063

1 file changed

Lines changed: 29 additions & 7 deletions

File tree

src/backEnd/model/Task.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,17 @@ def apply_header_rules(self):
179179
else:
180180
logger.debug(f"[{self.taskid}] No User-Agent header found to remove")
181181

182-
# 将请求头设置到SQLMap配置中
183-
# SQLMap期望headers是一个换行符分隔的字符串
184-
self.options.headers = "\n".join(self.headers)
182+
# 注意:不再设置 self.options.headers
183+
# 处理后的 headers 已存储在 self.headers 中,会由 _build_raw_http_request() 写入请求文件
184+
# 如果同时通过 options.headers (--headers) 和请求文件 (-r) 传递 headers,
185+
# sqlmap 会从两个来源接收 headers,导致:
186+
# 1. Connection: keep-alive 绕过 parseRequestFile 的过滤被强制添加,耗尽代理连接池
187+
# 2. Content-Length 被固定为原始值,与注入修改后的 body 长度不匹配
188+
# 3. 其他被 parseRequestFile 故意跳过的 headers(如 Proxy-Connection)也会被加回
185189

186190
if applied_rules:
187191
logger.info(f"[{self.taskid}] Applied {len(applied_rules)} header rules: {', '.join(applied_rules)}")
188-
logger.debug(f"[{self.taskid}] Set headers option for SQLMap: {self.options.headers}")
192+
logger.debug(f"[{self.taskid}] Processed headers for request file: {self.headers}")
189193

190194
# 标记请求头规则已应用
191195
self._header_rules_applied = True
@@ -383,7 +387,7 @@ def engine_start(self):
383387
# 在SQLMap真正启动前应用Body字段规则
384388
self.apply_body_field_rules()
385389

386-
logger.debug(f"[{self.taskid}] Headers option for SQLMap: {getattr(self.options, 'headers', 'Not set')}")
390+
logger.debug(f"[{self.taskid}] Headers in request file: {len(self.headers) if self.headers else 0} items")
387391

388392
# 创建HTTP原始报文文件
389393
self._request_file_path = self._create_request_file()
@@ -398,11 +402,29 @@ def engine_start(self):
398402

399403
logger.debug(f"[{self.taskid}] SQLMap config saved to {configFile}")
400404
logger.info(f"[{self.taskid}] Using request file mode (-r): {self._request_file_path}")
405+
406+
# 打印配置文件内容用于调试代理连接问题
407+
try:
408+
with open(configFile, 'r', encoding='utf-8') as cf:
409+
config_content = cf.read()
410+
logger.info(f"[{self.taskid}] === SQLMap Config File Content ===\n{config_content}")
411+
except Exception as e:
412+
logger.warning(f"[{self.taskid}] Failed to read config file for debug: {e}")
413+
414+
# 打印用户显式设置的选项(非默认值)
415+
logger.info(f"[{self.taskid}] User set options: {self._user_set_options}")
416+
logger.info(f"[{self.taskid}] proxy={self.options.get('proxy', 'NOT SET')}, "
417+
f"timeout={self.options.get('timeout', 'NOT SET')}, "
418+
f"threads={self.options.get('threads', 'NOT SET')}, "
419+
f"retries={self.options.get('retries', 'NOT SET')}, "
420+
f"keepAlive={self.options.get('keepAlive', 'NOT SET')}")
401421

402422
if os.path.exists("third_lib/sqlmap/sqlmap.py"):
403-
self.process = Popen([sys.executable or "python", "third_lib/sqlmap/sqlmap.py",
423+
cmd = [sys.executable or "python", "third_lib/sqlmap/sqlmap.py",
404424
"--api",
405-
"-c", configFile], shell=False,
425+
"-c", configFile]
426+
logger.info(f"[{self.taskid}] SQLMap launch command: {' '.join(cmd)}")
427+
self.process = Popen(cmd, shell=False,
406428
close_fds=not IS_WIN)
407429
elif os.path.exists(os.path.join(os.getcwd(), "sqlmap.py")):
408430
self.process = Popen([sys.executable or "python", "sqlmap.py",

0 commit comments

Comments
 (0)