Commit 3d50b08
committed
fix: harden Server Card discovery and close review gaps (experimental)
Discovery client:
- Bound each probe with DiscoveryPolicy.max_probe_entries (default 500),
an aggregate budget over every card and nested-catalog entry one walk
processes; exhaustion records a single "probe_budget" failure and drops
the rest. Already-visited nested catalog URLs are never refetched, so
cyclic or duplicated catalogs terminate. Without this the per-catalog
entry cap and the depth cap compose multiplicatively (~entries**depth
fetches from one hostile catalog).
- Catch OSError per entry too: an unresolvable host (socket.gaierror from
the guard's own DNS resolution) or a tar-pit entry (TimeoutError from
the per-fetch deadline) becomes a failure instead of killing the whole
probe, as the DiscoveryResult contract promises. Both exceptions are
now documented on the public fetchers.
- CardListing.listing_domain/hosting_domain return host[:port] built from
the parsed hostname, never the raw netloc, and _admit_url rejects
userinfo-carrying URLs outright, so https://github.com@evil.example/
can neither be fetched nor rendered as a trusted brand in consent UI.
- _is_blocked_address unwraps IPv4-mapped IPv6 literals and applies the
IPv4 rules, closing the ::ffff:100.64.0.1 CGNAT bypass (and the
private-range leak on interpreters without the gh-113171 fix).
- discover_server_cards with http_client=None opens one credential-free
client for the whole walk instead of one per fetched entry.
- Plain http is refused up front under the hardened policy (the loopback
carve-out was unreachable: loopback fails the address guard anyway).
- DiscoveryErrorReason is re-exported from the public module, and one
accept_header() helper replaces the duplicated Accept literals.
Models and server:
- Remote.required_variables now includes required headers that carry no
value and no default, keyed by header name exactly as resolve_remote
accepts them, so prompting from the property and then resolving works.
- mount_discovery documents that public_url is the app's public base URL.
- The discovery routes' CORSMiddleware allows only GET, so real browser
preflights advertise the spec's method list.
Tests cover the budget walk (exact fetch sequence), visited-set dedup,
per-entry DNS-failure and timeout resilience, userinfo rejection and
display, mapped-IPv6 blocking, required-header prompting, Repository and
icons round-trips, and the preflight headers.1 parent e15f284 commit 3d50b08
8 files changed
Lines changed: 446 additions & 56 deletions
File tree
- docs/advanced
- src/mcp
- client/experimental
- server/experimental
- tests
- client/experimental
- server/experimental
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
46 | 50 | | |
47 | 51 | | |
48 | 52 | | |
| |||
116 | 120 | | |
117 | 121 | | |
118 | 122 | | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
6 | | - | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
18 | | - | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
47 | 56 | | |
48 | 57 | | |
49 | 58 | | |
50 | 59 | | |
51 | 60 | | |
52 | 61 | | |
| 62 | + | |
53 | 63 | | |
54 | 64 | | |
55 | 65 | | |
| |||
71 | 81 | | |
72 | 82 | | |
73 | 83 | | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
74 | 94 | | |
75 | 95 | | |
76 | 96 | | |
| |||
111 | 131 | | |
112 | 132 | | |
113 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
114 | 139 | | |
115 | 140 | | |
116 | 141 | | |
| |||
121 | 146 | | |
122 | 147 | | |
123 | 148 | | |
124 | | - | |
125 | | - | |
126 | | - | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
127 | 153 | | |
128 | 154 | | |
129 | 155 | | |
130 | 156 | | |
131 | 157 | | |
132 | 158 | | |
133 | 159 | | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
134 | 166 | | |
135 | 167 | | |
136 | | - | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
137 | 172 | | |
138 | | - | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
139 | 176 | | |
140 | 177 | | |
141 | 178 | | |
| |||
162 | 199 | | |
163 | 200 | | |
164 | 201 | | |
165 | | - | |
| 202 | + | |
166 | 203 | | |
167 | 204 | | |
168 | 205 | | |
| |||
0 commit comments