Strip credentials from cross-origin request clones (nextLink follow-up) - #1551
Merged
Yabo Hu (VeryEarly) merged 5 commits intoAug 10, 2026
Conversation
YangAn-microsoft
marked this pull request as ready for review
August 5, 2026 03:48
YangAn-microsoft
force-pushed
the
fix/icm-nextlink-credential-forwarding
branch
from
August 6, 2026 04:55
abc27c3 to
e75a7d4
Compare
There was a problem hiding this comment.
Pull request overview
This PR mitigates credential leakage when a server-supplied follow-up URL (for example @odata.nextLink) changes the request’s origin, by preventing cloned requests from carrying sensitive credential headers across origins in the generated C# runtime.
Changes:
- Adds same-origin (scheme/host/port) + HTTPS gating to the runtime
HttpRequestMessage.Clonelogic. - Skips copying
Authorization,Proxy-Authorization, andCookieheaders on non-same-origin clones. - Updates emitter baselines so generated runtimes reflect the new clone behavior.
Reviewed changes
Copilot reviewed 1 out of 44 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| powershell/resources/runtime/csharp/pipeline/ISendAsync.cs | Runtime clone logic: compute same-origin + strip credential headers on cross-origin clones. |
| tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
| tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/ISendAsync.cs | Baseline update for runtime clone credential stripping. |
…solved cross-origin/non-https targets Addresses review feedback: relative same-origin nextLinks were misclassified as cross-origin (creds stripped); now resolve the target against the original request and compare the effective absolute origin. Null target (retry/same request) keeps headers. Runtime + 43 emitter baselines.
Yabo Hu (VeryEarly)
approved these changes
Aug 10, 2026
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.
Summary
Fixes credential forwarding where a server-supplied
@odata.nextLink(or other cross-origin follow-up) could cause the generated pipeline to forward the caller'sAuthorization: Bearertoken — plusCookie/Proxy-Authorization— to a different origin than the original request.What changed
Runtime
Clone(resources/runtime/csharp/pipeline/ISendAsync.cs):Authorization,Proxy-Authorization, andCookie.This is the standard "do not forward credentials across origins" mitigation, applied at the client-runtime layer.
Live test (real generated module, end-to-end)
Because Az PowerShell modules authenticate via Az.Accounts, we validated the whole behavior end-to-end using a real generated module built from this branch —
Az.MSGraph(the Azure PowerShellResourcesmodule) — driven by the realGet-AzADUsercmdlet against Microsoft Graph with a real signed-in context.A temporary trace (guarded by
AZ_NEXTLINK_TRACE) records the hashed credential at three points:PreAuth— pipeline entry, before the Az.Accounts auth step;PostAuth— pipeline terminal, emitted right before the request is sent on the wire (after auth);Clone— the retarget decision (strip vs retain).Tokens shown are truncated SHA-256 prefixes (no secrets, no tenant data).
Steps
npm run build).Az.MSGraphwith the local extension (autorest --use:<local powershell package>); verified the generated runtime contains this PR'sClonefix.Get-AzADUserresolves fromAz.MSGraph.Get-AzADUser -First 150(crosses a real@odata.nextLinkpage boundary).Normal path — real same-origin nextLink
Real Graph nextLinks are same-origin, so this PR retains the token (
isSameOrigin=True); paging returns 150. No regression.Cross-origin strip — same run, with a test-only toggle that forces the cross-origin branch on the absolute nextLink (real Graph never returns a cross-origin nextLink, so the decision is forced; the strip code exercised is this PR's unmodified logic):
COUNT=150— the call still succeeds.Conclusion
authClone=<none>).PostAuthcarries it again), so for Az PowerShell modules the runtime strip alone does not stop the forward — the auth step overrides it. Effective enforcement must live at (or be gated by) the Az.Accounts auth step; that change is tracked separately inAzure/azure-powershell.isSameOrigin/strip logic is unchanged.Testing
ISendAsync.cstargets).test-emittercompares freshly generated output against these committed baselines, so removing or altering the cross-origin credential strip in the runtime is caught by CI — i.e. the mitigation is continuously verified via the baselines.