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

Reply via email to