* Don't give attackers an opening by echoing back known bad parameter inputs.
authorNick Jenkins <nickj@users.mediawiki.org>
Thu, 19 Oct 2006 08:18:19 +0000 (08:18 +0000)
committerNick Jenkins <nickj@users.mediawiki.org>
Thu, 19 Oct 2006 08:18:19 +0000 (08:18 +0000)
* Create magic links only using a whitelist of protocols.

Have no proof of vuln, but allowing the user to make JavaScript links and have a lot of control over what goes into them probably isn't desirable.
Example attack input:
  http://en.wikipedia.org/w/api.php?action=query&meta=javascript://**/alert(1);

Example pre-patch HTML output contains this string:
  <a href="javascript://**/alert">javascript://**/alert</a>(1);
Which doesn't work, due to:
 1) the double slash - one slash someone can work around by faking a C-style comment (by appending "**/" as shown above), but two is a problem
 2) the parentheses being excluded, so we can't pass parameters
... but best to put a stop to it anyway.

includes/api/ApiBase.php
includes/api/ApiFormatBase.php

index b37ed66..719d724 100644 (file)
@@ -356,7 +356,7 @@ abstract class ApiBase {
                if (is_array($allowedValues)) {
                        $unknownValues = array_diff($valuesList, $allowedValues);
                        if ($unknownValues) {
-                               $this->dieUsage('Unrecognised value' . (count($unknownValues) > 1 ? "s '" : " '") . implode("', '", $unknownValues) . "' for parameter '$valueName'", "unknown_$valueName");
+                               $this->dieUsage('Unrecognised value' . (count($unknownValues) > 1 ? "s" : "") . " for parameter '$valueName'", "unknown_$valueName");
                        }
                }
 
index da515d5..9bc4e42 100644 (file)
@@ -147,7 +147,8 @@ for more information.
                // encode all tags as safe blue strings
                $text = ereg_replace('\<([^>]+)\>', '<span style="color:blue;">&lt;\1&gt;</span>', $text);
                // identify URLs
-               $text = ereg_replace("[a-zA-Z]+://[^ '\"()<\n]+", '<a href="\\0">\\0</a>', $text);
+               $protos = "http|https|ftp|gopher";
+               $text = ereg_replace("($protos)://[^ '\"()<\n]+", '<a href="\\0">\\0</a>', $text);
                // identify requests to api.php
                $text = ereg_replace("api\\.php\\?[^ ()<\n\t]+", '<a href="\\0">\\0</a>', $text);
                // make strings inside * bold