Skip to content

fix(oauth): allow http scheme for localhost and return nil on invalid host - #187

Open
Hardik K (hardikkaurani) wants to merge 8 commits into
microsoft:mainfrom
hardikkaurani:fix/oauth-allow-http-localhost
Open

Hardik K (hardikkaurani) wants to merge 8 commits into
microsoft:mainfrom
hardikkaurani:fix/oauth-allow-http-localhost

Conversation

@hardikkaurani

Copy link
Copy Markdown

Description

Fixes #117

This PR allows the http scheme for localhost and loopback targets in OAuthAccessTokenProvider, aligning Ruby with the behavior in Kiota Go (kiota-authentication-azure-go#102), Python, and PHP:

  1. Allow HTTP on Localhost:
    • Permits http scheme when the target host matches localhost, 127.0.0.1, ::1, or [::1].
    • Preserves HTTPS requirement for all external hosts (raise StandardError, 'Only https is supported').
  2. Proper Guard Return:
    • Fixed missing return on return nil if !uri || !@host_validator.url_host_valid?(uri) which previously evaluated nil as a statement without returning, allowing URI(uri) to be called with invalid/nil targets.

Related Issue

Fixes #117

Testing

Added RSpec tests in components/authentication/oauth/spec/microsoft_kiota_authentication_oauth_spec.rb:

  • Verifies get_authorization_token returns nil for nil or disallowed hosts.
  • Verifies http on localhost, 127.0.0.1, and [::1] successfully creates and resumes authentication fiber.
  • Verifies http on external non-localhost hosts raises StandardError, 'Only https is supported'.

cc Vincent Biret (@baywet)

@hardikkaurani
Hardik K (hardikkaurani) requested a review from a team as a code owner October 21, 2026 05:31
Copilot AI balanced review requested due to automatic review settings October 21, 2026 05:31
@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet), I've opened this PR to allow HTTP on localhost and loopback addresses in OAuthAccessTokenProvider (#117) and fix the guard return check for invalid hosts. Comprehensive RSpec tests are included. Ready for review!

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

🟡 Changes recommended

The nil return breaks the authentication caller, explicit allowlists block local HTTP, and localhost bypasses all scheme restrictions.

3 open issues

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 21, 2026 14:32

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Hardik K (hardikkaurani) commented Oct 21, 2026 •

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet),

I've addressed the review feedback in the latest commit.

Changes

  • Host and scheme validation: Updated AllowedHostsValidator#url_host_valid? to validate hosts independently of the URL scheme, including bracketed and unbracketed IPv6 loopback addresses.
  • Strict scheme enforcement: Updated OAuthAccessTokenProvider#get_authorization_token to allow HTTPS for external hosts and HTTP only for localhost/loopback targets. Unsupported schemes are rejected.
  • Fiber contract and defensive handling: Preserved the Fiber-based return contract for invalid or disallowed URLs and added a nil check before resuming the token fiber in BaseBearerTokenAuthenticationProvider#authenticate_request.
  • Regression coverage: Added tests for scheme-independent host validation, nil token fibers, invalid and untrusted URLs, localhost/loopback authentication, unsupported schemes, external HTTP rejection, and end-to-end authentication flows.

The changes are ready for review. When you have a chance, could you please take another look? Thank you for your time and feedback!

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.

🟢 Approval recommended

Static review identified no unresolved blocking issues, and regression tests cover the corrected behavior; tests were not executed.

1 open issue
2 resolved since last review

Review effort: Balanced

@baywet

Copy link
Copy Markdown
Member

Hardik K (@hardikkaurani) the linting is failing, would you mind fixing this please?

@hardikkaurani

Copy link
Copy Markdown
Author

Vincent Biret (@baywet) Just doing it !

Copilot AI balanced review requested due to automatic review settings October 21, 2026 16:29

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet)

I have updated the PR and resolved the RuboCop \Metrics/BlockLength\ offenses by modularizing the test suite into dedicated spec files matching the existing project structure (\�ase_bearer_token_authentication_provider_spec.rb\ and \oauth_access_token_provider_spec.rb).

  • All spec files are now well within RuboCop limits (< 152 lines).
  • All PR status checks (\Changelog PR Guard, \PullRequestConflicting, \license/cla) are green and the branch is up to date and mergeable.

Ready for review and workflow approval! Thank you!

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.

🟢 Approval recommended

Static review found no unresolved blocking issues, and targeted regression coverage addresses prior feedback; tests were not executed.

1 open issue

Review effort: Balanced

@hardikkaurani

Copy link
Copy Markdown
Author

Now also failing, just give me a minute !

I am taking a close look into this Vincent Biret (@baywet)

Comment thread components/abstractions/spec/request_information_uri_spec.rb Outdated
Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:14

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet),

I have fixed the linting offense in components/authentication/oauth/spec/microsoft_kiota_authentication_oauth_spec.rb by removing the extra blank line before the block end (Layout/EmptyLinesAroundBlockBody), which was the single offense causing the lint and check-ruby-version-matrix jobs to fail.

All modified files have been verified to have zero RuboCop offenses. The fix has been pushed in commit 2732a7a and is ready for workflow approval and review!

Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:38

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet),

I have updated the PR in commit d51b090 following your review feedback:

  1. Restored AllowedHostsValidator:
    • Reverted components/abstractions/lib/microsoft_kiota_abstractions/authentication/allowed_hosts_validator.rb back to its original state from main, preserving return false unless parsed_url.is_a?(URI::HTTPS) and removing square bracket stripping.
  2. Updated AllowedHostsValidator Spec:
    • Applied your suggestion in components/abstractions/spec/request_information_uri_spec.rb to assert expect(validator.url_host_valid?('http://example.com')).to be(false).
  3. Skipped Host Validation on Localhost Path in Provider:
    • In OAuthAccessTokenProvider#get_authorization_token, host validation is now bypassed specifically when the target is localhost (return Fiber.new { nil } if !is_localhost && !@host_validator.url_host_valid?(uri)), while strictly enforcing that only http or https schemes are permitted on localhost.
  4. Code Quality & RuboCop:
    • Verified 0 offenses across all files.

Ready for your review!

it 'validates host with https scheme and rejects non-https' do
validator = described_class.new(['example.com', 'localhost'])
expect(validator.url_host_valid?('http://example.com')).to be(false)
expect(validator.url_host_valid?('http://localhost:8080')).to be(false)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
expect(validator.url_host_valid?('http://localhost:8080')).to be(false)
expect(validator.url_host_valid?('http://localhost:8080')).to be(true)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated in 6c131f5: Updated AllowedHostsValidator#url_host_valid? to allow http scheme for localhost / loopback targets when included in �llowed_hosts, and updated this test expectation to o be(true).

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.

🟡 Changes recommended

Loopback URLs bypass explicit host restrictions, and external HTTP handling contradicts the documented exception behavior.

3 open issues

Review effort: Balanced

Comment thread components/authentication/oauth/spec/oauth_access_token_provider_spec.rb Outdated
Copilot AI balanced review requested due to automatic review settings October 21, 2026 19:19

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet),

I have updated the PR with commit 6c131f5 addressing your review suggestion and Copilot's review feedback:

  1. Localhost & Loopback Support in AllowedHostsValidator:

    • Updated AllowedHostsValidator#url_host_valid? to allow the http scheme for localhost, 127.0.0.1, ::1, and [::1] when included in allowed_hosts, while continuing to reject non-HTTPS external targets.
    • Applied your suggested change in components/abstractions/spec/request_information_uri_spec.rb: expect(validator.url_host_valid?('http://localhost:8080')).to be(true).
  2. Enforce Host Allowlist on Loopback Targets in OAuthAccessTokenProvider:

    • Removed the loopback allowlist bypass in OAuthAccessTokenProvider#get_authorization_token. Host membership is now enforced against @host_validator for all targets independently of scheme, ensuring unapproved loopback targets return a fiber resolving to nil.
    • Only explicitly allowlisted (or default empty) loopback targets receive tokens.
  3. Separate Host Matching from Scheme Enforcement:

    • Allowlisted external HTTP targets now cleanly reach the scheme validation step and raise StandardError, 'Only https is supported', while unapproved hosts silently return a fiber resolving to nil.
    • Updated unit tests in oauth_access_token_provider_spec.rb to cover all combinations: allowlisted external HTTP target raising Only https is supported, unapproved loopbacks/externals returning nil, and allowlisted loopbacks obtaining tokens.

Ready for your review! Thank you!

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.

🟡 Changes recommended

IPv6 normalization rejects previously supported bracketed allowlist entries, leaving explicitly approved requests unauthenticated.

1 open issue
3 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 23, 2026 13:26

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet),

I have updated the PR with commit 8af8838 addressing the IPv6 allowlist matching feedback:

  1. IPv6 Bracketed & Unbracketed Host Matching:

    • In AllowedHostsValidator#url_host_valid?, matching now inspects parsed_url.host.downcase first before stripping brackets or falling back to parsed_url.hostname. This ensures bracketed allowlist entries like ['[::1]'] correctly match bracketed IPv6 URLs (https://[::1]:8080/v1.0 and http://[::1]:8080/v1.0) without being dropped by URI#hostname.
    • Preserved stripped_host and hostname fallbacks to ensure unbracketed allowlist entries (['::1']) also match.
    • Updated localhost? in both AllowedHostsValidator and OAuthAccessTokenProvider to check host first, followed by hostname.
  2. Regression Test Coverage:

    • Added specs in components/abstractions/spec/request_information_uri_spec.rb verifying both ['[::1]'] and ['::1'] allowlists over HTTP and HTTPS loopback URLs, as well as confirming external targets remain rejected.
    • Updated components/authentication/oauth/spec/oauth_access_token_provider_spec.rb to validate end-to-end token acquisition for both bracketed and unbracketed allowlist entries.
  3. Status:

    • All tests across components/abstractions (127 examples) and components/authentication/oauth (11 examples) pass locally with 0 failures.
    • PR checks (check-changelog, label-merge-conflicts, license/cla) are green and the branch is clean.

Ready for your review! Thank you!

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.

🔵 Needs a closer look

Authentication scheme and allowlist changes still need validation on a supported Ruby runtime.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@hardikkaurani

Hardik K (hardikkaurani) commented Oct 23, 2026 •

Copy link
Copy Markdown
Author

Hi Vincent Biret (@baywet), I've addressed the review feedback and added regression tests for IPv6 allowlist handling. The relevant tests pass locally, and I've pushed the updates to the PR. When you have a chance, could you please take another look? Thank you for your time and feedback!

I've enjoyed contributing to Microsoft's open-source ecosystem and read your blog here: https://share.google/njEoOo6gDbfbit5Lf. I'd love to connect with you on LinkedIn and learn from your open-source experience. Thank you!

This PR is actually good to go with.

This branch has not been deployed

No deployments
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.

do not require https for local host in azure identity provider

3 participants