[wp-trac] [WordPress Trac] #36033: 'kses_allowed_protocols' filter is not really filterable.

WordPress Trac noreply at wordpress.org
Tue Mar 1 19:56:39 UTC 2016


#36033: 'kses_allowed_protocols' filter is not really filterable.
--------------------------+-----------------------------
 Reporter:  turtlepod     |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Security      |    Version:  4.4.2
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 in "wp_allowed_protocols()", "kses_allowed_protocols" filter only loaded
 once.

 And if "esc_url()" is called early, it will load "wp_allowed_protocols()"
 function and basically disable the filter.

 How to debug:

 1. add "mu-plugins" file with "esc_url()". example code:

 {{{
 <?php
 /* no not add empty string */
 esc_url( 'google.com' );
 }}}

 2. Now, no plugin will ever able to filter "kses_allowed_protocols"
 adding new protocols will not work. example plugin:
 https://wordpress.org/plugins/fx-skype-link-enabler/

 Reason:
 Here's the code for "wp_allowed_protocols()"
 https://developer.wordpress.org/reference/functions/wp_allowed_protocols/

 {{{
 function wp_allowed_protocols() {
     static $protocols = array();

     if ( empty( $protocols ) ) {
         $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto',
 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn',
 'tel', 'fax', 'xmpp', 'webcal' );

         /**
          * Filter the list of protocols allowed in HTML attributes.
          *
          * @since 3.0.0
          *
          * @param array $protocols Array of allowed protocols e.g. 'http',
 'ftp', 'tel', and more.
          */
         $protocols = apply_filters( 'kses_allowed_protocols', $protocols
 );
     }

     return $protocols;
 }
 }}}

 so, the filter only loaded once when this function is loaded for the first
 time.

 Suggestion:
 change it to something like:

 {{{
 function wp_allowed_protocols() {
     static $protocols = array();

     if ( empty( $protocols ) ) {
         $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto',
 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn',
 'tel', 'fax', 'xmpp', 'webcal' );
     }

     return apply_filters( 'kses_allowed_protocols', $protocols );
 }
 }}}

 and move the filters to final output of the function.

 Because:
 Correct me if I'm wrong:
 this filter is basically useless if user call "esc_url()" which call
 "wp_allowed_protocols()" and practically disable this filter. and make
 other plugin loaded later unable to add proper protocol for valid uses.

 -- David.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36033>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list