Skip to content

[Security][Advanced] _resolve_execution_timeout() accepts unbounded user input, sandbox_timeout cap silently bypassed #311

@anshul23102

Description

@anshul23102

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions