Page MenuHomePhabricator

ReDOS via Regex Injection in XTools
Closed, ResolvedPublicSecurity

Description

XTools tries to block crawlers rapidly crawling translations of pages based on the use of the uselang query parameter, while ignoring cases where the target project's language and the requested language are the same. However, this is checked by concatenating the language code directly in a regex (https://github.com/x-tools/xtools/blob/a2afff0d5425c7c8d9d0cd9881d9969c63eb72cc/src/EventSubscriber/RateLimitSubscriber.php#L175). This could be used to carry out ReDOS attacks by supplying uselang=(a+)+ in the URI which would result in the creation of this pattern of exponential time complexity: /[=\/](a+)+.?wik/.

Details

Risk Rating
Medium
Author Affiliation
Wikimedia Communities

Event Timeline

Why not use preg_quote() to mitigate this?

sbassett added subscribers: MusikAnimal, Samwilson, sbassett.

Why not use preg_quote() to mitigate this?

Yes, that should be sufficient:

> php -r "echo preg_quote('(a+)+');"
> \(a\+\)\+

Tagging a couple of the most recent project maintainers...

Like this?

diff --git a/src/EventSubscriber/RateLimitSubscriber.php b/src/EventSubscriber/RateLimitSubscriber.php
index 64b6bd28..31951c14 100644
--- a/src/EventSubscriber/RateLimitSubscriber.php
+++ b/src/EventSubscriber/RateLimitSubscriber.php
@@ -172,7 +172,7 @@ class RateLimitSubscriber implements EventSubscriberInterface {
 
                // If requesting the same language as the target project, ignore.
                // FIXME: This has side-effects (T384711#10759078)
-               if ( preg_match( "/[=\/]$useLang.?wik/", $this->uri ) === 1 ) {
+               if ( preg_match( '/[=\/]' . preg_quote( $useLang ) . '?wik/', $this->uri ) === 1 ) {
                        return;
                }

Adding another XTools maintainer.

taavi subscribed.

Does not seem to be a Cloud-VPS infrastructure issue, thus untagging us.

Like this?
...

Yep, that's sufficient.

The best path forward here is to probably create a public pull request for the xtools repo and then quickly merge and deploy it to the cloud project.

Done:

https://github.com/x-tools/xtools/pull/615
https://github.com/x-tools/xtools/pull/616

And I've released version 3.24.1 with the change. That will be auto deployed within ten minutes.

Done:

https://github.com/x-tools/xtools/pull/615
https://github.com/x-tools/xtools/pull/616

And I've released version 3.24.1 with the change. That will be auto deployed within ten minutes.

Thanks! I'd like to resolve this task and make it public now unless you have any other concerns.

Yep fine by me. Unless @Redmin wants to double-check first?

Nah, thanks for patching this; it looks good.

sbassett triaged this task as Medium priority.
sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from N/A to Medium.