Skip to content

Security hardening: token validation and service URL improvements#418

Merged
corinagum merged 9 commits into
mainfrom
cg/security
Apr 21, 2026
Merged

Security hardening: token validation and service URL improvements#418
corinagum merged 9 commits into
mainfrom
cg/security

Conversation

@corinagum

@corinagum corinagum commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Security hardening for token validation, service URL handling, and development tooling.

  • Service URL validation: Validate inbound ServiceUrl against allowed hostnames from the configured CloudEnvironment preset. Configurable via AdditionalAllowedDomains on AppOptions (also settable in appsettings.json).
  • Issuer validation: Log a warning when Entra token validation is configured without a tenant ID, making the silent issuer validation skip visible.
  • DevTools: Prevent the DevTools plugin from starting in production environments.

Test plan

  • Unit tests for ServiceUrlValidator (cloud preset FQDNs, rejected domains, localhost, empty/null, invalid URLs, additional domains, wildcard, cross-cloud rejection, botframework.com rejected by default)
  • E2E validated in Teams -- no regressions
  • E2E validated DevTools blocked on ASPNETCORE_ENVIRONMENT=Production

@rido-min

Copy link
Copy Markdown
Contributor

Configurable via AdditionalAllowedDomains and SkipServiceUrlValidation
on AppOptions

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

Comment thread Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs Outdated
@corinagum
corinagum marked this pull request as ready for review April 17, 2026 19:05
Copilot AI review requested due to automatic review settings April 17, 2026 19:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ServiceUrlValidator and enforce service URL allowlist validation during App.Process(...).
  • Extend CloudEnvironment with per-cloud allowed service URL hostnames and plumb AdditionalAllowedDomains from configuration into AppOptions.
  • 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.

Comment thread Tests/Microsoft.Teams.Apps.Tests/ServiceUrlValidatorTests.cs
Comment thread Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs Outdated
Comment thread Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs
Comment thread Libraries/Microsoft.Teams.Apps/App.cs
Comment thread Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs Outdated
Comment thread Libraries/Microsoft.Teams.Apps/ServiceUrlValidator.cs Outdated
Comment thread Libraries/Microsoft.Teams.Api/Auth/CloudEnvironment.cs Outdated
singhk97
singhk97 previously approved these changes Apr 20, 2026
@corinagum
corinagum merged commit b9bc522 into main Apr 21, 2026
7 checks passed
@corinagum
corinagum deleted the cg/security branch April 21, 2026 16:32
corinagum added a commit to microsoft/teams-sdk that referenced this pull request Apr 22, 2026
## 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
corinagum added a commit that referenced this pull request Apr 28, 2026
## 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants