Page MenuHomePhabricator

Uncaught PHP Exception InvalidArgumentException: "Unable to parse URI: <gibberish>" at /var/www/tool/vendor/guzzlehttp/psr7/src/Uri.php line 72
Closed, ResolvedPublicBUG REPORT

Description

Lately I've been receiving several alerts like this one:

message
Uncaught PHP Exception InvalidArgumentException: "Unable to parse URI: https://en);waitfor delay '0:0:5'--.wikisource.org/w/index.php?title=MediaWiki:WS_Export.json&action=raw&ctype=application/json" at /var/www/tool/vendor/guzzlehttp/psr7/src/Uri.php line 72
exception
{
    "class": "InvalidArgumentException",
    "message": "Unable to parse URI: https://en);waitfor delay '0:0:5'--.wikisource.org/w/index.php?title=MediaWiki:WS_Export.json&action=raw&ctype=application/json",
    "code": 0,
    "file": "/var/www/tool/vendor/guzzlehttp/psr7/src/Uri.php:72",
    "trace": [
        "/var/www/tool/vendor/guzzlehttp/psr7/src/Utils.php:393",
        "/var/www/tool/vendor/guzzlehttp/psr7/src/functions.php:41",
        "/var/www/tool/vendor/guzzlehttp/guzzle/src/Client.php:211",
        "/var/www/tool/vendor/guzzlehttp/guzzle/src/Client.php:154",
        "/var/www/tool/vendor/guzzlehttp/guzzle/src/Client.php:182",
        "/var/www/tool/vendor/guzzlehttp/guzzle/src/Client.php:95",
        "/var/www/tool/src/Util/Api.php:286",
        "/var/www/tool/src/Util/OnWikiConfig.php:47",
        "/var/www/tool/vendor/symfony/cache/LockRegistry.php:99",
        "/var/www/tool/vendor/symfony/cache/Traits/ContractsTrait.php:88",
        "/var/www/tool/vendor/symfony/cache-contracts/CacheTrait.php:70",
        "/var/www/tool/vendor/symfony/cache/Traits/ContractsTrait.php:95",
        "/var/www/tool/vendor/symfony/cache-contracts/CacheTrait.php:33",
        "/var/www/tool/src/Util/OnWikiConfig.php:61",
        "/var/www/tool/src/Util/OnWikiConfig.php:72",
        "/var/www/tool/src/FontProvider.php:45",
        "/var/www/tool/src/Controller/ExportController.php:189",
        "/var/www/tool/src/Controller/ExportController.php:139",
        "/var/www/tool/src/Controller/ExportController.php:103",
        "/var/www/tool/vendor/symfony/http-kernel/HttpKernel.php:157",
        "/var/www/tool/vendor/symfony/http-kernel/HttpKernel.php:79",
        "/var/www/tool/vendor/symfony/http-kernel/Kernel.php:196",
        "/var/www/tool/public/index.php:35"
    ]
}

URL: http://ws-export.wmcloud.org/?format=epub-3&lang=en%29%3BWAITFOR%20DELAY%20%270%3A0%3A5%27--&page=Una_and_the_Lion

Seems like somebody is running the usual pentests on the tool. Nonetheless, I've also seen similar errors for "normal" URLs, since any malformed URL can cause it.

The URL above currently returns a 500 error, with a generic-looking error box and causing an email to be sent. Instead, I think the exception should be caught, a specific error message should be shown, and we should get no alert.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
MusikAnimal raised the priority of this task from High to Needs Triage.Jun 21 2021, 1:54 AM

I've taken a look. For starters, I couldn't find a reliable way to validate the URL beforehand: guzzle itself doesn't seem to have a validateURL() method. The only candidate is Uri::parse in guzzle/psr7; this is also what's used by Uri::__construct, so the validation would also match the final result. However, we can't use it for two reasons:

  • The method is private
  • And even if it were public, IMHO it wouldn't make much sense to call it manually, since it'd be called again shortly afterwards

Instead, the first thing that comes to mind is to catch the exception. The problem is that the exception in question is an InvalidArgumentException, which is terribly generic, and thrown by a method 7 calls deeper in the call stack than where we can catch it. This means a high risk of catching an unrelated InvalidArgumentException. Plus, I'd consider it bad practice to catch an InvalidArgumentException, since I see it more of a way to report a programming error, rather than a runtime issue.

All in all, things would be much easier with guzzle/psr7 throwing a dedicated exception, i.e. MalformedUriException; I'm not sure why this isn't already the case in the first place. I guess I might open an issue/PR upstream, although that would be a compatibility break for any consumer that's already catching InvalidArgumentException for invalid URL detection.

https://github.com/guzzle/psr7/issues/426

Oh, and FTR: I don't want to use filter_var, parse_url or a custom regexp. Since the URL is being fed to a library that does custom validation, we cannot guarantee that the two validation methods will agree on all possible URIs.

@Daimona I note the upstream issue has been closed — can this task be resolved?

@Daimona I note the upstream issue has been closed — can this task be resolved?

I think so, especially if you're not getting any alerts like the one in the task description.