[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