Make WordPress Core

Opened 5 years ago

Last modified 14 months ago

#34407 new defect (bug)

esc_url() cannot handle a relative URL containing a : character (IPv6)

Reported by: dd32 Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Formatting Keywords:
Focuses: Cc:


Split off from #34202 / #34054

When using a relative URL with esc_url() nothing will be returned if the string contains a : character, for example, one which occurs within an IPv6 address.

This will output nothing:

echo esc_url( 'edit-comments.php?s=2001:0db8:0000:0000:0000:ff00:0042:8329' );

The cause boils down to wp_kses_bad_protocol() which through wp_kses_bad_protocol_once() assumes anything before : in a URL is a protocol.

Relative URL's such as /edit-comments.php?s=2001:0db8.. succeed as esc_url() identifies them as relative, and never calls wp_kses_bad_protocol().

Change History (5)

#1 @dd32
5 years ago

#34054 was marked as a duplicate.

#2 @dd32
5 years ago

In 35368:

Comments: Use a full URL rather than a relative one for links which can contain IPv6 addresses to avoid an issue where the URL was being eaten by escaping functions.

See #34407, #34202
Fixes #34054

This ticket was mentioned in Slack in #core by dd32. View the logs.

5 years ago

#4 @dd32
5 years ago

  • Component changed from General to Formatting

#5 @jadpm
4 years ago

Note thst this is also broken when trying to escape a URL that contains a port number:
error_log( esc_url( 'http://example.com:8080' ) );// Outputs http://example.com:8080
error_log( esc_url( 'example.com' ) );// Outputs http://example.com
error_log( esc_url( 'example.com:8080' ) );// Outputs an empty string

That means that URLs containing no protocol but a port number can not be sanitized. The only solution for now is to include the protocol.

Note: See TracTickets for help on using tickets.