Repository navigation
Validate region URLs before failing over to them - #1052
Merged
Merged
Conversation
xianshijing-lk
requested review from
MaxHeimbrock and
davidliu
as code owners
October 29, 2026 20:46
🦋 Changeset detectedLatest commit: a7cd3ad The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
|
Diffuse output: AARJAR |
`isLKCloud()` is checked against the server URL the application supplied, to decide whether region discovery applies at all. The URLs that came back were then used as they arrived: `RegionInfo` holds whatever string the response carried, and `getNextBestRegionUrl()` hands it straight to the connect path. Those URLs are not just connected to, they are authenticated to -- `fetchRegionSettings` sends the participant token as a bearer header, and `Room` calls `connectionWarmer.fetch(regionUrl)` on one before a connection attempt even starts. An entry should stand on its own merits rather than inherit trust from the configured server URL, and it should not be able to move that exchange onto cleartext. Add `isTrustedRegionUrl`: the URL must parse, name a `.livekit.cloud` or `.livekit.run` host, and use `wss` or `https`. Apply it in `applyRegionSettings`, which both ingestion paths now go through -- the `/settings/regions` fetch and `setServerReportedRegions`, which takes the regions the server reports over signaling. Both were unvalidated before. Rejected entries are logged rather than dropped silently. Unlike `isLKCloud()`, this check has no testing override. The existing `regionUrlProviderTesting` flag exists so a mock server URL passes the cloud check; it must not also make the SDK accept an untrusted region, and no release build can clear the new check. The host match is case-insensitive, since `URI.getHost()` preserves the case the response used. Six tests: the predicate against encrypted cloud URLs, cleartext schemes, foreign hosts, suffix near-misses and malformed input, plus one test per ingestion path. Both ingestion tests fail without the filter.
davidliu
force-pushed
the
security/validate-region-urls
branch
from
October 30, 2026 09:51
9a9aff7 to
44e518f
Compare
davidliu
approved these changes
Oct 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Android port of livekit/rust-sdks#1601 and livekit/client-sdk-swift#1182.
What
isLKCloud()is checked against the server URL the application supplied, to decide whether region discovery applies at all. The URLs that came back were then used as they arrived —RegionInfoholds whatever string the response carried, andgetNextBestRegionUrl()hands it straight to the connect path.Those URLs are not just connected to, they are authenticated to:
fetchRegionSettingssends the participant token as a bearer header, andRoomcallsconnectionWarmer.fetch(regionUrl)on one before a connection attempt even starts. An entry should stand on its own merits rather than inherit trust from the configured server URL, and it should not be able to move that exchange onto cleartext.How
isTrustedRegionUrl: the URL must parse, name a.livekit.cloud/.livekit.runhost, and usewssorhttps.applyRegionSettings, which both ingestion paths now go through — the/settings/regionsfetch andsetServerReportedRegions, which takes the regions the server reports over signaling. Both were unvalidated before.Note on the testing override
Unlike
isLKCloud(), the new check has no testing override.regionUrlProviderTestingexists so a mock server URL passes the cloud check; it must not also make the SDK accept an untrusted region. No release build can clear the new check.The host match is case-insensitive, since
URI.getHost()preserves whatever case the response used.Tests
Six new tests: the predicate against encrypted cloud URLs, cleartext schemes, foreign hosts, suffix near-misses (
not-livekit.cloud,livekit.cloud.example.com) and malformed input — plus one per ingestion path. Both ingestion tests verified to fail without the filter.RegionUrlProviderTestpasses.spotlessCheckclean, anddetektfinding count is unchanged from the baseline onmain(90).Heads-up, unrelated to this PR
:livekit-android-test:testDebugUnitTesthas 84 pre-existing failures onmain, all inDataStreamsV2ReceiveTest. I confirmed the count is identical with and without this change, so they are not caused here — butmainis currently red.🤖 Generated with Claude Code