Opened 8 months ago

Last modified 6 weeks ago

#21974 new defect (bug)

esc_url() doesn't allow protocol-relative URLs with colons

Reported by: SergeyBiryukov Owned by:
Priority: normal Milestone: 3.6
Component: Formatting Version:
Severity: normal Keywords: has-patch
Cc:

Description

This doesn't work:

wp_enqueue_style( 'twentytwelve-fonts', "//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700", array(), null );

The colon is the culprit. wp_kses_bad_protocol() reduces the URL to:

400italic,700italic,400,700

So esc_url() returns an empty string:
http://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/formatting.php#L2572

Attachments (4)

21974.patch (518 bytes) - added by SergeyBiryukov 8 months ago.
21974.unit-test.patch (943 bytes) - added by SergeyBiryukov 8 months ago.
21974.2.patch (537 bytes) - added by SergeyBiryukov 6 weeks ago.
21974.3.patch (753 bytes) - added by SergeyBiryukov 6 weeks ago.

Download all attachments as: .zip

Change History (11)

21974.patch only calls wp_kses_bad_protocol() if the URL doesn't start with a slash. There's a similar detection earlier:
http://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/formatting.php#L2559

Perhaps wp_kses_bad_protocol() should be patched instead?

  • Keywords has-patch added

comment:3 follow-up: ↓ 6   nacin7 months ago

  • Component changed from General to Formatting
  • Milestone changed from 3.5 to Future Release

Technically, a colon is a "reserved" character which means outside of its official use, it must be encoded. This reminds me of #16859.

#23853 was marked as a duplicate.

comment:6 in reply to: ↑ 3   SergeyBiryukov6 weeks ago

  • Milestone changed from Future Release to 3.6

Replying to nacin:

Technically, a colon is a "reserved" character which means outside of its official use, it must be encoded.

An encoded colon (: or :) doesn't work either.

wp_kses_bad_protocol_once() splits by any of those values:
http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/kses.php#L1053

And esc_url() still returns an empty string.

I guess we shouldn't call wp_kses_bad_protocol() at all for a protocol-relative URL. Refreshed the patch.

21974.2.patch just fixes the issue.

21974.3.patch also skips the strtolower() check, which is redundant in this case.

Last edited 6 weeks ago by SergeyBiryukov (previous) (diff)

#23853 was marked as a duplicate.

Note: See TracTickets for help on using tickets.