Skip to content

fix(security): isolate plugin parser subprocess network#1737

Open
anshul23102 wants to merge 1 commit into
utksh1:mainfrom
anshul23102:fix/1620-parser-network-isolation
Open

fix(security): isolate plugin parser subprocess network#1737
anshul23102 wants to merge 1 commit into
utksh1:mainfrom
anshul23102:fix/1620-parser-network-isolation

Conversation

@anshul23102

Copy link
Copy Markdown
Contributor

Split out of #1700 per review feedback -- this PR is scoped to issue #1620 only.

Problem

Plugin parsers previously inherited the parent's full network stack. A malicious parser.py could exfiltrate scan findings to an attacker-controlled server over a plain socket, with no control in place.

Fix

On Linux with unprivileged user namespaces, spawn parser subprocesses in a fresh network namespace with unshare --user --net. The child has no network interfaces configured except a loopback that is down by default, so it cannot reach any host. Parsers only transform text already captured from the scanner (never network-bound); they have zero legitimate need for network access.

Unshare capability is probed once at startup via _unshare_net_supported(), which checks platform, binary availability, and runtime support. On non-Linux hosts or if the capability check fails for any reason (restrictive container runtime, disabled user namespaces, etc.), we warn once and fail open, spawning without isolation, rather than refusing all plugins. The broader threat model is documented in docs/plugins/plugin-security-checklist.md.

Testing

  • testing/backend/integration/test_parser_network_isolation.py: 4 tests covering capability probe, argv construction with/without isolation, and successful parser execution under isolation -- all passing
  • ruff check backend/secuscan/parser_sandbox.py -- all checks passed

Fixes #1620

Issue utksh1#1620: plugin parsers previously inherited the parent's full network
stack. A malicious parser.py could exfiltrate scan findings to an
attacker-controlled server over a plain socket, with no control here.

Fix: on Linux with unprivileged user namespaces, spawn parser subprocesses
in a fresh network namespace with 'unshare --user --net'. The child has
no network interfaces configured except a loopback that is down by default,
so it cannot reach any host. Parsers only transform text already captured
from the scanner (never network-bound); they have zero legitimate need
for network access.

Unshare capability is probed once at startup via _unshare_net_supported(),
which checks platform, binary availability, and runtime support. On
non-Linux hosts or if the capability check fails for any reason
(restrictive container runtime, disabled user namespaces, etc.), we warn
once and fail open, spawning without isolation, rather than refusing
all plugins. The broader threat model is documented in
docs/plugins/plugin-security-checklist.md.

Testing:
- testing/backend/integration/test_parser_network_isolation.py: 4 tests
  covering capability probe, argv construction with/without isolation,
  and successful parser execution under isolation.
- pytest testing/backend/integration -q -m "not benchmark" -- 288 passed,
  9 skipped (284 baseline + 4 new)
- ruff check backend/secuscan/parser_sandbox.py -- all checks passed

Fixes utksh1#1620
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security: plugin subprocess runs with no outbound network isolation

1 participant