Skip to content

fix(web): match IPv6 loopback hostname with brackets in isPrivateOrLo… - #40152

Open
zl86790 wants to merge 5 commits into
langgenius:mainfrom
zl86790:fix/ipv6-loopback-hostname-bracket-mismatch
Open

fix(web): match IPv6 loopback hostname with brackets in isPrivateOrLo…#40152
zl86790 wants to merge 5 commits into
langgenius:mainfrom
zl86790:fix/ipv6-loopback-hostname-bracket-mismatch

Conversation

@zl86790

@zl86790 zl86790 commented Aug 7, 2026

Copy link
Copy Markdown

Summary

isPrivateOrLocalAddress() in web/utils/urlValidation.ts is supposed to flag localhost, private IP ranges, and .local addresses so the UI can warn users. The IPv6 loopback check never actually works though:

if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') return true

URL.hostname serializes IPv6 addresses with brackets, so for http://[::1]/ the hostname is the string "[::1]", not "::1". The comparison never matches, so isPrivateOrLocalAddress('http://[::1]/') silently returns false — it falls through every other check and ends up treated as a public address.

new URL('http://[::1]:8080/').hostname // "[::1]"

Ran it before/after the fix:

http://[::1]/       before: false   after: true
http://[::1]:8080/  before: false   after: true

Two places use this to warn users about private/local endpoints, and both silently skip the warning for IPv6 loopback:

  • web/app/components/workflow/nodes/trigger-webhook/panel.tsx:199 (webhook debug URL)
  • web/app/components/plugins/plugin-detail-panel/subscription-list/create/hooks/use-common-modal-state.helpers.ts:171 (plugin subscription callback URL)

Fix is just matching the bracketed form instead:

if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]') return true

Kept this scoped to just the loopback comparison. isPrivateOrLocalAddress also doesn't cover fe80::/10 (link-local) or fd00::/8 (ULA) IPv6 ranges, but that's a separate gap, not something this bug touches — didn't want to bundle it in here.

isPrivateOrLocalAddress had zero test coverage before this, so added a small one covering the loopback case this PR fixes.

Screenshots

N/A — logic fix, no UI change.

Checklist

  • This change requires a documentation update
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint && make type-check (backend) and cd web && pnpm exec vp staged (frontend) to appease the lint gods

…calAddress

URL.hostname serializes IPv6 addresses with brackets (e.g. "[::1]"),
but the localhost check compared against the unbracketed "::1", so
it never matched and IPv6 loopback URLs weren't flagged as
private/local.
@zl86790
zl86790 requested a review from iamjoel as a code owner August 7, 2026 10:27
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Aug 7, 2026
@github-actions github-actions Bot added the web This relates to changes on the web. label Aug 7, 2026

@anujbolewar anujbolewar left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The IPv6 loopback recognition is right, and the test for the bracket form is welcome given the parser here returns the hostname without braces for ::1. A cleaner approach is to strip and normalize brackets once at the top of this function, then compare against the bare values, which avoids two subtly different comparisons. Also note this only covers IPv6 loopback, not other private v6 ranges such as fe80; worth deciding whether that is in scope or a follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files. web This relates to changes on the web.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants