Samwilson has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/406017 )
Change subject: Add prefix support to URL whitelist ...................................................................... Add prefix support to URL whitelist Permit URLs in the whitelist to end in '*' in order to permit any that start with the given prefix. Bug: T185087 Change-Id: I458aa74f1862d4da6bf162f996ff4a8b3dcba580 --- M RSSHooks.php M extension.json 2 files changed, 60 insertions(+), 26 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/RSS refs/changes/17/406017/1 diff --git a/RSSHooks.php b/RSSHooks.php index 3968257..4c598e3 100644 --- a/RSSHooks.php +++ b/RSSHooks.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\MediaWikiServices; + class RSSHooks { /** @@ -23,8 +25,7 @@ * @return string */ static function renderRss( $input, array $args, Parser $parser, PPFrame $frame ) { - global $wgRSSCacheAge, $wgRSSCacheCompare, $wgRSSNamespaces, - $wgRSSUrlWhitelist,$wgRSSAllowedFeeds; + global $wgRSSCacheAge, $wgRSSCacheCompare, $wgRSSNamespaces, $wgRSSAllowedFeeds; if ( is_array( $wgRSSNamespaces ) && count( $wgRSSNamespaces ) ) { $ns = $parser->getTitle()->getNamespace(); @@ -39,30 +40,10 @@ return RSSUtils::RSSError( 'rss-deprecated-wgrssallowedfeeds-found' ); } - # disallow because there is no whitelist at all or an empty whitelist - - if ( !isset( $wgRSSUrlWhitelist ) - || !is_array( $wgRSSUrlWhitelist ) - || ( count( $wgRSSUrlWhitelist ) === 0 ) ) { - return RSSUtils::RSSError( 'rss-empty-whitelist', - $input - ); - - } - - # disallow the feed url because the url is not whitelisted; or - # disallow because the wildcard joker is not present to allow any feed url - # which can be dangerous - - if ( !( in_array( $input, $wgRSSUrlWhitelist ) ) - && !( in_array( "*", $wgRSSUrlWhitelist ) ) ) { - $listOfAllowed = $parser->getFunctionLang()->listToText( $wgRSSUrlWhitelist ); - $numberAllowed = $parser->getFunctionLang()->formatNum( count( $wgRSSUrlWhitelist ) ); - - return RSSUtils::RSSError( 'rss-url-is-not-whitelisted', - [ $input, $listOfAllowed, $numberAllowed ] - ); - + // Check the input against the configured whitelist of URLs. + $whitelistError = static::checkAgainstWhitelist( $input, $parser->getFunctionLang() ); + if ( $whitelistError ) { + return $whitelistError; } if ( !Http::isValidURI( $input ) ) { @@ -93,4 +74,54 @@ return $rss->renderFeed( $parser, $frame ); } + /** + * Check whether a given URL is in the configured whitelist of RSS URLs. + * @param string $inputUrl The URL to check. Can be '*' to allow any, + * or end in '*' to allow any prefix. + * @param Language $language The language to use for the error message list and numbers. + * @return string The error message if the URL is not allowed, or an empty string if it is. + */ + protected static function checkAgainstWhitelist( $inputUrl, Language $language ) { + // Get the whitelist. + $whitelist = MediaWikiServices::getInstance() + ->getConfigFactory() + ->makeConfig('RSS' ) + ->get( 'RSSUrlWhitelist' ); + + // Disallow because there is an empty whitelist. + if ( !isset( $whitelist ) || !is_array( $whitelist ) || ( count( $whitelist ) === 0 ) ) { + return RSSUtils::RSSError( 'rss-empty-whitelist', $inputUrl ); + } + + // Check for exact match or asterisk. + $whitelisted = in_array( $inputUrl, $whitelist ) || in_array( '*', $whitelist ); + // Otherwise, check for a match for URLs that end in an asterisk (T185087). + if ( !$whitelisted ) { + $whitelistedUrls = array_filter( + $whitelist, + function ( $whitelistedUrl ) use ( $inputUrl ) { + if ( substr( $whitelistedUrl, -1 ) !== '*' ) { + // If it's not a wildcard whitelisted URL. + return false; + } + // See if the supplied URL starts with the whitelisted prefix. + $whitelistedPrefix = substr( $whitelistedUrl, 0, -1 ); + $inputUrlPrefix = substr( $inputUrl, 0, strlen( $whitelistedPrefix ) ); + return $inputUrlPrefix === $whitelistedPrefix; + } + ); + // It's whitelisted if it matches any of the whitelist prefixes. + $whitelisted = ( count( $whitelistedUrls ) > 0 ); + } + if ( !$whitelisted ) { + // If it's not whitelisted, construct the error message. + $listOfAllowed = $language->listToText( $whitelist ); + $numberAllowed = $language->formatNum( count( $whitelist ) ); + return RSSUtils::RSSError( + 'rss-url-is-not-whitelisted', + [ $inputUrl, $listOfAllowed, $numberAllowed ] + ); + } + return ''; + } } diff --git a/extension.json b/extension.json index c5450d6..e433cdb 100644 --- a/extension.json +++ b/extension.json @@ -52,5 +52,8 @@ "RSSAllowLinkTag": false, "RSSAllowImageTag": false }, + "ConfigRegistry": { + "RSS": "GlobalVarConfig::newInstance" + }, "manifest_version": 1 } -- To view, visit https://gerrit.wikimedia.org/r/406017 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I458aa74f1862d4da6bf162f996ff4a8b3dcba580 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/RSS Gerrit-Branch: master Gerrit-Owner: Samwilson <s...@samwilson.id.au> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits