Make WordPress Core

Changeset 38890


Ignore:
Timestamp:
10/24/2016 08:06:06 PM (10 years ago)
Author:
westonruter
Message:

Customize: Harden url matching to account for varying ports and ensuring matching base pathname for allowed urls

Fixes #38409.

Location:
trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/customize-controls.js

    r38889 r38890  
    40414041
    40424042                        previewer.add( 'previewUrl', params.previewUrl ).setter( function( to ) {
    4043                                 var result, urlParser, newPreviewUrl, schemeMatchingPreviewUrl, queryParams;
     4043                                var result = null, urlParser, queryParams, parsedAllowedUrl, parsedCandidateUrls = [];
    40444044                                urlParser = document.createElement( 'a' );
    40454045                                urlParser.href = to;
     
    40634063                                }
    40644064
    4065                                 newPreviewUrl = urlParser.href;
    4066                                 urlParser.protocol = previewer.scheme.get() + ':';
    4067                                 schemeMatchingPreviewUrl = urlParser.href;
     4065                                parsedCandidateUrls.push( urlParser );
     4066
     4067                                // Prepend list with URL that matches the scheme/protocol of the iframe.
     4068                                if ( previewer.scheme.get() + ':' !== urlParser.protocol ) {
     4069                                        urlParser = document.createElement( 'a' );
     4070                                        urlParser.href = parsedCandidateUrls[0].href;
     4071                                        urlParser.protocol = previewer.scheme.get() + ':';
     4072                                        parsedCandidateUrls.unshift( urlParser );
     4073                                }
    40684074
    40694075                                // Attempt to match the URL to the control frame's scheme
    40704076                                // and check if it's allowed. If not, try the original URL.
    4071                                 $.each( [ schemeMatchingPreviewUrl, newPreviewUrl ], function( i, url ) {
    4072                                         $.each( previewer.allowedUrls, function( i, allowed ) {
    4073                                                 var path;
    4074 
    4075                                                 allowed = allowed.replace( /\/+$/, '' );
    4076                                                 path = url.replace( allowed, '' );
    4077 
    4078                                                 if ( 0 === url.indexOf( allowed ) && /^([/#?]|$)/.test( path ) ) {
    4079                                                         result = url;
    4080                                                         return false;
     4077                                parsedAllowedUrl = document.createElement( 'a' );
     4078                                _.find( parsedCandidateUrls, function( parsedCandidateUrl ) {
     4079                                        return ! _.isUndefined( _.find( previewer.allowedUrls, function( allowedUrl ) {
     4080                                                parsedAllowedUrl.href = allowedUrl;
     4081                                                if ( urlParser.protocol === parsedAllowedUrl.protocol && urlParser.host === parsedAllowedUrl.host && 0 === parsedAllowedUrl.pathname.indexOf( urlParser.pathname ) ) {
     4082                                                        result = parsedCandidateUrl.href;
     4083                                                        return true;
    40814084                                                }
    4082                                         });
    4083                                         if ( result ) {
    4084                                                 return false;
    4085                                         }
    4086                                 });
    4087 
    4088                                 // If we found a matching result, return it. If not, bail.
    4089                                 return result ? result : null;
     4085                                        } ) );
     4086                                } );
     4087
     4088                                return result;
    40904089                        });
    40914090
  • trunk/src/wp-includes/js/customize-base.js

    r38810 r38890  
    655655                                var urlParser = document.createElement( 'a' );
    656656                                urlParser.href = to;
    657                                 return urlParser.protocol + '//' + urlParser.hostname;
     657                                // Port stripping needed by IE since it adds to host but not to event.origin.
     658                                return urlParser.protocol + '//' + urlParser.host.replace( /:80$/, '' );
    658659                        });
    659660
  • trunk/src/wp-includes/js/customize-preview.js

    r38829 r38890  
    276276         * @param {string} element.search Query string.
    277277         * @param {string} element.pathname Path.
    278          * @param {string} element.hostname Hostname.
     278         * @param {string} element.host Host.
    279279         * @param {object} [options]
    280280         * @param {object} [options.allowAdminAjax=false] Allow admin-ajax.php requests.
     
    282282         */
    283283        api.isLinkPreviewable = function isLinkPreviewable( element, options ) {
    284                 var hasMatchingHost, urlParser, args;
     284                var matchesAllowedUrl, parsedAllowedUrl, args;
    285285
    286286                args = _.extend( {}, { allowAdminAjax: false }, options || {} );
     
    295295                }
    296296
    297                 urlParser = document.createElement( 'a' );
    298                 hasMatchingHost = ! _.isUndefined( _.find( api.settings.url.allowed, function( allowedUrl ) {
    299                         urlParser.href = allowedUrl;
    300                         if ( urlParser.hostname === element.hostname && urlParser.protocol === element.protocol ) {
    301                                 return true;
    302                         }
    303                         return false;
     297                parsedAllowedUrl = document.createElement( 'a' );
     298                matchesAllowedUrl = ! _.isUndefined( _.find( api.settings.url.allowed, function( allowedUrl ) {
     299                        parsedAllowedUrl.href = allowedUrl;
     300                        return parsedAllowedUrl.protocol === element.protocol && parsedAllowedUrl.host === element.host && 0 === element.pathname.indexOf( parsedAllowedUrl.pathname );
    304301                } ) );
    305                 if ( ! hasMatchingHost ) {
     302                if ( ! matchesAllowedUrl ) {
    306303                        return false;
    307304                }
     
    332329         *
    333330         * @param {HTMLAnchorElement|HTMLAreaElement} element Link element.
    334          * @param {object} element.search Query string.
     331         * @param {string} element.search Query string.
     332         * @param {string} element.host Host.
     333         * @param {string} element.protocol Protocol.
    335334         * @returns {void}
    336335         */
     
    349348
    350349                // Make sure links in preview use HTTPS if parent frame uses HTTPS.
    351                 if ( 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.hostname ) ) {
     350                if ( 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.host ) ) {
    352351                        element.protocol = 'https:';
    353352                }
     
    497496
    498497                // Make sure forms in preview use HTTPS if parent frame uses HTTPS.
    499                 if ( 'https' === api.preview.scheme.get() && 'http:' === urlParser.protocol && -1 !== api.settings.url.allowedHosts.indexOf( urlParser.hostname ) ) {
     498                if ( 'https' === api.preview.scheme.get() && 'http:' === urlParser.protocol && -1 !== api.settings.url.allowedHosts.indexOf( urlParser.host ) ) {
    500499                        urlParser.protocol = 'https:';
    501500                        form.action = urlParser.href;
Note: See TracChangeset for help on using the changeset viewer.