Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 14, 2026

java.net.URI.getHost() returns host without port, while cbSecurity.getRealHost() returns host:port. This caused valid same-host redirects to be rejected during development on non-default ports, collapsing _securedURL to /.

Example scenario:

URI.getHost()   = "127.0.0.1"
getRealHost()   = "127.0.0.1:61910"

Direct comparison fails even though hosts match.

Changes

  • interceptors/Security.cfc (L832): Strip port from getRealHost() before comparing with URI.getHost()

    var currentHost = listFirst( variables.cbSecurity.getRealHost(), ":" );
  • test-harness/tests/specs/unit/SecurityTest.cfc: Added test coverage for:

    • Non-default ports with matching hosts
    • Different ports with matching hosts (should allow)
    • Different hosts with matching ports (should block)

Open redirect protection remains intact—only hostnames are compared regardless of port.

Original prompt

This section details on the original issue you should resolve

<issue_title>isSafeRedirectUrl host comparison fails on non-default ports</issue_title>
<issue_description>### Bug: isSafeRedirectUrl host comparison fails on non-default ports

Problem
java.net.URI.getHost() returns host without port, while
cbSecurity.getRealHost() returns host:port.

This causes valid same-host redirects to be rejected when running on
non-default ports (e.g. during dev), collapsing
_securedURL to /.

Example
URI.getHost() = 127.0.0.1
URI.getPort() = 61910
getRealHost() = 127.0.0.1:61910

Direct comparison fails even though the host is the same.

Fix
Normalize getRealHost() to host-only before comparison.

Patch - /Interceptors/Security.cfc (line 828)

// Get the current request's host for comparison
// Normalize host: urlToValidate.getHost() does not include port
// Strip port from .getRealHost() for compare
var currentHost = listFirst( variables.cbSecurity.getRealHost(), ":" );

// Compare hosts (case-insensitive)
return compareNoCase( urlToValidate.getHost(), currentHost ) == 0;

/Patch</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

- Strip port from getRealHost() before comparing with URI.getHost()
- Add test cases for non-default port scenarios
- Fixes issue where valid same-host redirects were rejected during dev

Co-authored-by: lmajano <137111+lmajano@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix isSafeRedirectUrl host comparison for non-default ports Fix isSafeRedirectUrl host comparison on non-default ports Jan 14, 2026
Copilot AI requested a review from lmajano January 14, 2026 18:13
@github-actions
Copy link

github-actions bot commented Jan 14, 2026

adobe@2023 ColdBox ^7.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

lucee@5 ColdBox ^7.0.0 Test Results

113 tests  +3   113 ✅ +3   7s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

boxlang-cfml@be ColdBox 8 Test Results

113 tests  +3   113 ✅ +3   7s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

boxlang-cfml@1 ColdBox 8 Test Results

113 tests  +3   113 ✅ +3   8s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

boxlang-cfml@1 ColdBox be Test Results

113 tests  +3   113 ✅ +3   8s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

boxlang-cfml@1 ColdBox ^8.0.0 Test Results

113 tests  +3   113 ✅ +3   7s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

adobe@2025 ColdBox ^8.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

lucee@6 ColdBox ^7.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

adobe@2025 ColdBox ^7.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

adobe@2023 ColdBox be Test Results

113 tests  +3   113 ✅ +3   6s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

lucee@6 ColdBox ^8.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

lucee@6 ColdBox be Test Results

113 tests  +3   113 ✅ +3   6s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

lucee@5 ColdBox ^8.0.0 Test Results

113 tests  +3   113 ✅ +3   8s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

boxlang-cfml@1 ColdBox ^7.0.0 Test Results

113 tests  +3   113 ✅ +3   8s ⏱️ -1s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

adobe@2023 ColdBox ^8.0.0 Test Results

113 tests  +3   113 ✅ +3   5s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 009d388. ± Comparison against base commit 3a79195.

♻️ This comment has been updated with latest results.

@lmajano lmajano marked this pull request as ready for review January 14, 2026 18:21
Copilot AI review requested due to automatic review settings January 14, 2026 18:21
@lmajano lmajano merged commit 0efc178 into development Jan 14, 2026
48 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where isSafeRedirectUrl incorrectly rejected valid same-host redirects when running on non-default ports. The issue occurred because java.net.URI.getHost() returns the hostname without the port, while cbSecurity.getRealHost() returns host:port, causing direct string comparison to fail.

Changes:

  • Fixed host comparison logic to strip port from getRealHost() before comparing with URI.getHost()
  • Added comprehensive test coverage for port-related edge cases
  • Preserved open redirect protection while allowing same-host redirects regardless of port

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
interceptors/Security.cfc Modified isSafeRedirectUrl to extract hostname without port using listFirst() before comparison
test-harness/tests/specs/unit/SecurityTest.cfc Added three new test cases covering non-default ports, different ports with same host, and different hosts with same port

Comment on lines +830 to 833
// Normalize host: urlToValidate.getHost() does not include port
// Strip port from .getRealHost() for compare
var currentHost = listFirst( variables.cbSecurity.getRealHost(), ":" );

Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

Using listFirst(..., ':') to extract the hostname will break for IPv6 addresses, which contain multiple colons (e.g., 2001:db8::1:8080 or [2001:db8::1]:8080). When an IPv6 address with port is encountered, this will only return the first segment (e.g., 2001), causing the comparison to fail. Consider using a more robust approach that handles IPv6 addresses by checking for bracketed addresses first, or using listLast() to get the port and then removing it, or using Java's URI parsing capabilities.

Suggested change
// Normalize host: urlToValidate.getHost() does not include port
// Strip port from .getRealHost() for compare
var currentHost = listFirst( variables.cbSecurity.getRealHost(), ":" );
// Normalize host: urlToValidate.getHost() does not include port and supports IPv6
// Use java.net.URI to safely parse .getRealHost() (which may include port and/or IPv6)
var realHost = variables.cbSecurity.getRealHost();
var currentHost = "";
// Ensure we have a scheme so java.net.URI can parse the host correctly
var currentUriString = reFindNoCase( "^[a-z][a-z0-9+.-]*://", realHost )
? realHost
: "http://" & realHost;
try {
var currentUri = createObject( "java", "java.net.URI" ).init( currentUriString );
currentHost = currentUri.getHost();
// Fallback to the raw value if getHost() returned null
if ( isNull( currentHost ) || !len( currentHost ) ) {
currentHost = realHost;
}
} catch ( any ignore ) {
// If parsing fails, fall back to the raw value
currentHost = realHost;
}

Copilot uses AI. Check for mistakes.
Comment on lines +345 to +354
it( "allows URLs with non-default ports when host matches", () => {
// Simulate getRealHost returning host with port (e.g., during dev)
mockSecurityService.$( "getRealHost", "127.0.0.1:61910" );

var result = security.isSafeRedirectUrl(
targetUrl = "http://127.0.0.1:61910/account",
event = mockEvent
);
expect( result ).toBeTrue();
} );
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

Test coverage is missing for IPv6 addresses with ports (e.g., http://[::1]:8080/path or http://[2001:db8::1]:9000/account). IPv6 addresses contain multiple colons, which could break the current listFirst(..., ':') implementation. Add test cases for IPv6 addresses with and without ports to ensure the fix works correctly for all address types.

Copilot uses AI. Check for mistakes.
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.

isSafeRedirectUrl host comparison fails on non-default ports

2 participants