Secure mediated VM egress - #436
Conversation
a707997 to
8684213
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e69387c. Configure here.
| if err := insertAcceptHostTCPRule(sourceIP, proxyPort, enforcementComment(instanceID, enforcementSuffixHostProxy)); err != nil { | ||
| removeEgressRules(instanceID) | ||
| return fmt.Errorf("insert host proxy allowance: %w", err) | ||
| } |
There was a problem hiding this comment.
Anti-spoof rules lose to later accepts
High Severity
In all mode, host ACCEPT rules for DNS and the proxy are inserted at INPUT position 1 after anti-spoof DROP rules, so they are evaluated first. Those accepts match only source IP, not TAP. A guest can spoof a VM that registered later, skip that VM's anti-spoof rule, and reach the proxy as the victim. The proxy then applies the victim's registered policy, including header injection of its secrets.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e69387c. Configure here.
| commentAllTCP := enforcementComment(instanceID, enforcementSuffixAllTCP) | ||
| _ = removeRuleByComment(comment80) | ||
| _ = removeRuleByComment(comment443) | ||
| _ = removeRuleByComment(commentAllTCP) |
There was a problem hiding this comment.
Failed inserts leave leftover rules
Medium Severity
After anti-spoof rules are installed, a failed insertRejectAllTCPRule or port-80 insertRejectRule returns without removeEgressRules. Other failures in the same function do roll back. Registration then fails, create/start cleanup does not unregister, and those TAP/source rules can remain until a later successful apply for the same instance ID.
Reviewed by Cursor Bugbot for commit e69387c. Configure here.
|
Closing because Quickbox does not need a second egress-enforcement boundary for the employee beta. We will rely on Hypeman’s existing VM isolation and revisit mediated egress only if outbound policy or credential injection becomes a product requirement. |


Summary
Why
Bridge forwarding does not preserve the TAP device as the logical input interface, so interface-matched enforcement could be bypassed. The proxy also accepted unregistered VM sources and could dial private or special-purpose addresses.
Testing
go test -race ./lib/egressproxygo test ./lib/instances -run '^(TestValidateCreateRequest_|TestRestoreEgress)' -count=1\n-go vet ./lib/egressproxy ./lib/instances\n\nThe full instances integration suite was not run locally because it requires root networking and host image-conversion dependencies; CI covers it.Note
High Risk
Changes host iptables enforcement and proxy SSRF/source-auth behavior for VM egress, which is security-critical networking. A rule or resolver bug could leak host/private access or drop legitimate traffic.
Overview
Hardens mediated VM egress so guests cannot bypass the proxy or reach private/special-purpose addresses.
Linux iptables rules now match each instance source IP instead of TAP interface name (which is lost after bridge forwarding). They also drop spoofed TAP traffic, reject new TCP to the host except DNS and the proxy port in
allmode, and use conntrack NEW state.The proxy itself 403s unregistered source IPs and dials only public global-unicast destinations (
publicDialContext), preferring IPv4 when both families resolve. Mixed public/private DNS answers are treated as blocked.Reviewed by Cursor Bugbot for commit e69387c. Bugbot is set up for automated code reviews on this repo. Configure here.