Summary
_resolve_execution_timeout() in backend/secuscan/executor.py (lines 491-501) accepts any positive integer from user-supplied inputs as the execution timeout with no upper bound. A caller can pass max_scan_time=2147483647 and override the operator-configured settings.sandbox_timeout = 600, pinning a worker thread for days and exhausting the concurrent task pool.
Affected File
backend/secuscan/executor.py, lines 491-501
def _resolve_execution_timeout(self, inputs: Dict[str, Any]) -> int:
for key in ("max_scan_time", "timeout"):
raw_value = inputs.get(key)
try:
timeout = int(raw_value)
except (TypeError, ValueError):
continue
if timeout > 0:
return timeout
return settings.sandbox_timeout
The only check is timeout > 0. Any integer that passes that guard is used verbatim, completely bypassing settings.sandbox_timeout.
Reproduction
POST /tasks
{
"plugin_id": "nmap",
"inputs": {
"target": "192.168.1.1",
"max_scan_time": 2147483647
}
}
The spawned subprocess will be allowed to run for ~68 years. The concurrent_limiter slot is held for the entire duration, starving all subsequent scans.
Impact
Fix
Clamp the resolved value against settings.sandbox_timeout:
if timeout > 0:
return min(timeout, settings.sandbox_timeout)
This honours the operator's intended upper limit while still allowing callers to request shorter timeouts.
Environment
- File:
backend/secuscan/executor.py
- Function:
_resolve_execution_timeout
- Related:
settings.sandbox_timeout in settings module
Summary
_resolve_execution_timeout()inbackend/secuscan/executor.py(lines 491-501) accepts any positive integer from user-supplied inputs as the execution timeout with no upper bound. A caller can passmax_scan_time=2147483647and override the operator-configuredsettings.sandbox_timeout = 600, pinning a worker thread for days and exhausting the concurrent task pool.Affected File
backend/secuscan/executor.py, lines 491-501The only check is
timeout > 0. Any integer that passes that guard is used verbatim, completely bypassingsettings.sandbox_timeout.Reproduction
The spawned subprocess will be allowed to run for ~68 years. The
concurrent_limiterslot is held for the entire duration, starving all subsequent scans.Impact
settings.sandbox_timeoutexists specifically to cap untrusted input runtimes; this path silently ignores it.Fix
Clamp the resolved value against
settings.sandbox_timeout:This honours the operator's intended upper limit while still allowing callers to request shorter timeouts.
Environment
backend/secuscan/executor.py_resolve_execution_timeoutsettings.sandbox_timeoutin settings module