microsoft / microsoft/agent-governance-toolkit
cross-SDK pattern: approval webhook URL validation is literal-hostname / construction-time only (DNS rebinding); Go PoC exploited end-to-end
- Dominant language
- Python
- Stars
- 6.3k
- Forks
- 1.1k
- Avg merge
- 5d 11h
- Merged PRs (30d)
- 142
Description
Adversarial review of #3242 exploited this end-to-end in Go: validateApprovalWebhookURL (approval_webhook.go:270) checks only the literal hostname at construction; http://127.0.0.1.nip.io:/hook passed validation, POSTed to loopback, and produced a full ALLOW with consumed execution. The same class exists in .NET (#3363's WebhookApprover.cs:178, literal-hostname + constructor-time-only) and the Python relay connect path re-resolves at request time (noted on #3242's review). Recommended shared fix spec so the bug is not re-ported: resolve the hostname at REQUEST time, validate every resolved IP against the deny-set (loopback/link-local/RFC1918 metadata ranges), and pin the validated IP via DialContext/SocketsHttpHandler so the request cannot re-resolve elsewhere. Regression test: a rebinding hostname (nip.io style) must be rejected. Applies to: Go #3242 (blocking ask posted-pending), .NET #3363 (follow-up), and an audit of any other webhook/HTTP-out surface (agent-mesh relay, TRACE sinks).
Contributor guide
Research direction
Start with validateApprovalWebhookURL in approval_webhook.go:270, then compare WebhookApprover.cs:178 and the Python relay connect path noted in #3242. Review the shared fix specification and audit the agent-mesh relay and TRACE sinks. Done means request-time resolution rejects every denied IP, connection pinning prevents re-resolution, and a nip.io-style rebinding regression test fails safely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, go, python
- Domain
- networking, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100