Security hardening: token validation and service URL improvements#418
Conversation
These two options seems overlaping, we could skip service UrlValidation by calling AdditionalAllowedDomains with a magic string such as *. Wondering if we could override the addtional domains from config |
There was a problem hiding this comment.
Pull request overview
Security hardening across the Teams app runtime and ASP.NET Core plugins by validating inbound service URLs before using them for outbound Bot Framework calls, improving visibility into Entra issuer-validation configuration, and preventing DevTools from running in production.
Changes:
- Add
ServiceUrlValidatorand enforce service URL allowlist validation duringApp.Process(...). - Extend
CloudEnvironmentwith per-cloud allowed service URL hostnames and plumbAdditionalAllowedDomainsfrom configuration intoAppOptions. - Add production-environment blocking for DevTools and emit a warning when Entra validation is configured without a tenant ID.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/Microsoft.Teams.Apps.Tests/ServiceUrlValidatorTests.cs | Adds unit tests covering allowed/rejected service URL scenarios. |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/TeamsValidationSettings.cs | Adds a warning path when tenant ID is missing for Entra issuer validation. |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/DevToolsPlugin.cs | Blocks DevTools initialization in Production via IHostEnvironment. |
| Libraries/Microsoft.Teams.Extensions/Microsoft.Teams.Extensions.Configuration/Microsoft.Teams.Apps.Extensions/TeamsSettings.cs | Adds AdditionalAllowedDomains configuration and applies it to AppOptions. |
| Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs | Introduces service URL hostname validation against cloud defaults + additional domains. |
| Libraries/Microsoft.Teams.Apps/AppOptions.cs | Adds AdditionalAllowedDomains option for runtime configuration. |
| Libraries/Microsoft.Teams.Apps/App.cs | Enforces service URL validation before creating ConversationReference used for outbound calls. |
| Libraries/Microsoft.Teams.Api/Auth/CloudEnvironment.cs | Adds AllowedServiceUrls and populates defaults per cloud; extends WithOverrides. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…able param, immutable array, devtools guard fallback
## Summary Documentation for security hardening changes shipping in the SDK PRs: - microsoft/teams.ts#515 - microsoft/teams.py#370 - microsoft/teams.net#418 ### New page: Service URL Validation `src/pages/templates/essentials/service-url-validation.mdx` + per-language include files Documents the service URL domain allowlist: - Allowed hostnames by cloud environment preset - How to add custom domains via `additionalAllowedDomains` - Sovereign cloud FQDNs that require manual configuration - How to disable validation with wildcard `*` - Note on proactive messaging ## Test plan - [x] Docusaurus builds without errors - [x] New page renders correctly for all 3 languages - [x] Admonitions render correctly
## Summary Reverting the serviceUrl allowlist defense-in-depth feature before public release. Open design questions on the work item (default sovereign cloud domains, narrowing of `*.botframework.com`, applying to proactive `ConversationReference`s, consultation with APX) should be resolved before this becomes part of the public API surface. This feature has not shipped in any release. Removing the public `AdditionalAllowedDomains` option is a breaking change for anyone building from `main`, which is not ideal but acceptable since no release has been cut. Reverting now buys time to discuss without breaking customers later. ## Removed - `ServiceUrlValidator` class and `ServiceUrlValidatorTests` - `AppOptions.AdditionalAllowedDomains`, `App._additionalAllowedDomains` field, related warn log, and the `IsAllowed` check in `App.Process` - `TeamsSettings.AdditionalAllowedDomains` and its `Apply()` assignment - `CloudEnvironment.AllowedServiceUrls` property, per-cloud entries (Public/USGov/USGovDoD/China), constructor parameter, and `WithOverrides` parameter ## Preserved (other security work bundled into PR #418) - DevTools production guard (`DevToolsPlugin`, `TeamsValidationSettings`) ## Preserved (sovereign cloud, separate work) `CloudEnvironment` presets, `WithOverrides`, `FromName`, `AppOptions.Cloud`, and the per-cloud `Bots.Token.ActiveBotScope` / `ActiveGraphScope` / `TokenServiceUrl` wiring in `App` are unchanged. ## Note on related open PRs PR #450 (`Tighten AdditionalAllowedDomains API contract`) and PR #413 (sovereign cloud next/core, which carries this plumbing) are intentionally left open for separate decisions. ## Test plan - [x] `dotnet build` clean (0 errors, 5 unrelated pre-existing warnings) - [x] `dotnet test` net10.0 passes (net8.0 testhost aborted on local machine due to missing SDK, environmental, not code) - [x] Smoke test: `Samples/Samples.Echo` starts and binds to port
Summary
Security hardening for token validation, service URL handling, and development tooling.
ServiceUrlagainst allowed hostnames from the configuredCloudEnvironmentpreset. Configurable viaAdditionalAllowedDomainsonAppOptions(also settable inappsettings.json).Test plan
ServiceUrlValidator(cloud preset FQDNs, rejected domains, localhost, empty/null, invalid URLs, additional domains, wildcard, cross-cloud rejection, botframework.com rejected by default)ASPNETCORE_ENVIRONMENT=Production