Repository navigation
Improved SSRF protection for aiohttp clients - #621
Conversation
…into users/robrandao/host-validator
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Supported aiohttp compatibility, SSRF regressions, and positional API compatibility must be addressed.
Review effort: Balanced
Findings: 5
Open (9)
Retain HTTP scheme restriction without a validator · New Retain baseline URL checks before sending credentials · New Reject loopback, link-local, and unspecified addresses · New Prevent proxies from bypassing destination validation · New Raise aiohttp minimum version or avoid client middleware · New Preserve deprecated client_factory positional argument · New Preserve M365 client_factory positional argument · New Restore deprecated outbound host validator module · New Remove unused imports causing flake8 failures · New
What changed in this PR
Hardens outbound HTTP requests against SSRF by introducing DNS-aware aiohttp validation and refactoring attachment downloaders.
Changes:
- Adds HTTPS, hostname, and resolved-address validation.
- Routes attachment downloads through configurable sessions.
- Expands security tests and release notes.
| File | Description |
|---|---|
changelog.md |
Documents v1.9.0 security and API changes. |
core/__init__.py |
Re-exports the relocated validator. |
core/_http_adapter_base.py |
Uses the new security package. |
app/attachment_downloader.py |
Refactors generic attachment HTTP handling. |
app/m365_attachment_downloader.py |
Refactors authenticated M365 downloads. |
core/outbound_host_validator.py |
Removes the former validator module. |
security/__init__.py |
Defines security package exports. |
security/_connector.py |
Adds DNS-result validation. |
security/_middleware.py |
Adds per-request URL validation. |
security/_utils.py |
Adds URL and hostname helpers. |
security/_validator.py |
Defines validator protocols. |
security/outbound_host_validator.py |
Implements host and address enforcement. |
test_attachment_downloader.py |
Updates generic downloader tests. |
test_m365_attachment_downloader.py |
Updates M365 downloader tests. |
test_outbound_host_validator.py |
Expands SSRF validator coverage. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Copilot review overview
Review effort: Lite
Findings: 1
Open (5)
aiohttp.ClientSession(at least up through aiohttp versions prior to my cutoff) does not accept a… · New Ignoringclient_factorycan silently change behavior for existing callers (even if logged). Since… · New The raised_SSRFErrorincludes the full outbound URL string. In real usage, URLs can contain… · New@lru_cacheon an instance method will store entries keyed by(self, _url)and can keep… · New The docstring duplicates:param connections:and does not document the new… · New
Resolved since last review (9)
Raise aiohttp minimum version or avoid client middleware Prevent proxies from bypassing destination validation Reject loopback, link-local, and unspecified addresses Retain baseline URL checks before sending credentials Retain HTTP scheme restriction without a validator Restore deprecated outbound host validator module Preserve M365 client_factory positional argument Preserve deprecated client_factory positional argument Remove unused imports causing flake8 failures
…ress normalization for allow list
…icrosoft/Agents-for-python into users/robrandao/host-validator
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Full signed URLs can leak through warnings, and the migration currently breaks legacy positional constructors and direct validator imports.
Review effort: Balanced
Findings: 2
Open (3)
Resolved since last review (5)
aiohttp.ClientSession(at least up through aiohttp versions prior to my cutoff) does not accept a…@lru_cacheon an instance method will store entries keyed by(self, _url)and can keep… The raised_SSRFErrorincludes the full outbound URL string. In real usage, URLs can contain… Ignoringclient_factorycan silently change behavior for existing callers (even if logged). Since… The docstring duplicates:param connections:and does not document the new…
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Update warning message for outbound host validation failure. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>



This pull request introduces significant security and API improvements to outbound host validation and attachment downloading in the Microsoft 365 Agents SDK for Python. The changes harden the outbound host validation logic, enforce stricter SSRF protections, and update the attachment downloader APIs to ensure all HTTP requests are subject to proper validation and middleware. There are also breaking changes to the configuration of HTTP clients in attachment downloaders, and internal refactoring to support the new security model.
Security and SSRF Protection Enhancements:
aiohttpconnector (_SSRFConnector) and middleware to validate resolved IPv4/IPv6 addresses before connecting, and centralized outbound host validation logic in a newsecuritymodule. ([[1]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-3875bfbcb9ea8837ee9a1f73d954c3276da1e40b9a644e025bb44b2075fcc765R1-R58),[[2]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-5149530c7e4213ccababfaab3cdf0941362d0a4746fb771a4bcf77b25e96d887R1-R33),[[3]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-418c5e8a12d4343ddb8cfceb0ca854762c062339a1917d18ff4a197723f4ef92R1-R14))OutboundHostValidatorto enforce HTTPS-only URLs, validate DNS resolution for public (and optionally private) network addresses, and ensure all outbound requests are checked. ([changelog.mdR1-R15](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R1-R15))Attachment Downloader API and Behavior Changes (Breaking):
client_factoryparameter inAttachmentDownloaderandM365AttachmentDownloaderwithclient_session_kwargs, ensuring all HTTP requests use the validator-managed session and middleware; the deprecatedclient_factoryparameter is now ignored with a warning. ([[1]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R1-R15),[[2]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-9ccafddd8f5872de4e2396e1f2a41a7982841c60e9f7607e5c9bbbb831ffb43fL16-R50),[[3]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-9ccafddd8f5872de4e2396e1f2a41a7982841c60e9f7607e5c9bbbb831ffb43fR65-R94),[[4]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-2b67a6e4aced3470f33e270effcca8103143ad53af29c0e254959d787fc4dae0R5-R63),[[5]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-2b67a6e4aced3470f33e270effcca8103143ad53af29c0e254959d787fc4dae0R123-R148))[[1]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-9ccafddd8f5872de4e2396e1f2a41a7982841c60e9f7607e5c9bbbb831ffb43fR116-R121),[[2]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-2b67a6e4aced3470f33e270effcca8103143ad53af29c0e254959d787fc4dae0L138-R166),[[3]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-2b67a6e4aced3470f33e270effcca8103143ad53af29c0e254959d787fc4dae0R186-R190))Internal Refactoring and Module Organization:
securitypackage, updating imports throughout the codebase. ([[1]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-2ae76148988270389664a1036a2a0ec3a9d581355eea25046e29e5f441a85822L12-R14),[[2]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-0598d213e59e6f09f7a0a172f0a1584a752afe5831f844778ffe23f097193bcaL26-R26),[[3]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-418c5e8a12d4343ddb8cfceb0ca854762c062339a1917d18ff4a197723f4ef92R1-R14))outbound_host_validator.pyfile, consolidating logic in the newsecuritymodule. ([libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/outbound_host_validator.pyL1-L117](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-cd57f33b1ab8881d8512c0a2db86ccfa997d30a8de2e63ef91c3ab88305994b3L1-L117))Default Behavior and Backward Compatibility:
OutboundHostValidatorto be disabled unless explicitly enabled, and updated adapter initialization accordingly. ([[1]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-0598d213e59e6f09f7a0a172f0a1584a752afe5831f844778ffe23f097193bcaL83-R83),[[2]](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-0598d213e59e6f09f7a0a172f0a1584a752afe5831f844778ffe23f097193bcaL208-R208))Documentation and Release Notes:
[changelog.mdR1-R15](https://github.com/microsoft/Agents-for-python/pull/621/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R1-R15))