feat(analyzer): detect Docker socket access as PE4 privilege escalation#189
Conversation
Add PE4_PATTERNS to the static privilege escalation analyzer to detect Docker socket access, which allows a containerized skill to gain full host root without triggering any of the existing PE1-PE3 rules. Four patterns are added: - /var/run/docker.sock (socket path, confidence 0.9) - docker.from_env() (SDK entry point, confidence 0.85) - DockerClient( (explicit client construction, confidence 0.85) - http+unix://...docker.sock (raw HTTP-over-socket, confidence 0.9) Closes NVIDIA#188 Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
Resolved conflict in test_static_patterns.py — kept both TestRunStaticPatternsPrivilegeEscalationPE4 (this branch) and TestRunStaticPatternsSSRF (upstream feat/ssrf-analyzer). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
| matched_text=match.group(0)[:200], | ||
| ) | ||
| ) | ||
| for pattern, confidence in PE4_PATTERNS: |
There was a problem hiding this comment.
[Automated SkillSpector Review]
Non-blocking: a line containing more than one PE4 marker (e.g. DockerClient(base_url="unix:///var/run/docker.sock") matches both \bDockerClient\s*\( and /var/run/docker\.sock) will append two PE4 findings for the same location. Consider de-duplicating per (rule_id, line) or breaking after the first PE4 hit on a line to avoid double-counting.
rng1995
left a comment
There was a problem hiding this comment.
[Automated SkillSpector Review]
Approved.
Genuinely valuable detection: Docker socket access (/var/run/docker.sock, docker.from_env(), DockerClient(, http+unix://...docker.sock) is a direct container->host-root escalation that previously produced zero findings under --no-llm. The PE4 loop mirrors the existing PE1-PE3 structure, honors _is_documentation_example, and ships positive/negative/doc-filter/node tests.
Non-blocking nit: a single line such as docker.DockerClient(base_url="unix:///var/run/docker.sock") matches both the DockerClient( and /var/run/docker.sock patterns, producing two PE4 findings on one line. Consider de-duping per (rule, line) or breaking after the first PE4 match. (mergeable_state: blocked is branch protection, not a code issue.)
…rting A line such as `docker.DockerClient(base_url="unix:///var/run/docker.sock")` matched both the `DockerClient(` and `/var/run/docker.sock` PE4 patterns, producing two findings for the same vulnerability on the same line. Collect PE4 candidates in a dict keyed by line number, keeping only the highest-confidence match, then extend the findings list once. Adds a regression test that asserts exactly one PE4 finding on such a combined line. Addresses nit raised in review of PR NVIDIA#189. Signed-off-by: CharmingGroot <hogeun.choi@vicsnc.com> Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
|
Addressed the nit in 34309b3: PE4 findings are now deduplicated per line by collecting candidates in a |
Summary
Closes #188
Adds
PE4_PATTERNSto the static privilege escalation analyzer to detect Docker socket access. This attack allows a containerized skill to gain full host root access without triggering any of the existing PE1–PE3 rules.Four patterns are added to
src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py:/var/run/docker\.sockdocker\.from_env\(\)\bDockerClient\s*\(http\+unix://.*docker\.sockBefore / After
Before (static analysis only,
--no-llm)docker.from_env()in a Python skill file produced zero findings — the skill installed without any warning.After (static analysis only,
--no-llm)Docker socket access is now caught by the static layer without requiring LLM analysis.
Testing
7 new unit tests in
TestRunStaticPatternsPrivilegeEscalationPE4: positive cases for all four patterns (/var/run/docker.sock,docker.from_env(),DockerClient(,http+unix://...docker.sock), a negative case forsubprocess.run(['docker', 'ps'])which carries no socket reference, a filter case confirmingdocker.from_env()inside a markdown code block is suppressed by_is_documentation_example(), and a node entrypoint test confirmingprivilege_escalation_module.node()returns PE4 findings.make lintandmake formatpassed.make test— 937 passed (2 pre-existing failures intest_meta_analyzer.pyunrelated to this change).