Page MenuHomePhabricator

Parsoid REST API does not check access permissions of user - allowed information disclosure for private or semi-private wikis (e.g. affecting VisualEditor + Lockdown)
Closed, DeclinedPublicSecurity

Description

Hi security guys.

Unuseful but funny preamble

During a very, very, very tiring nightly assembly of my local Wikimedia chapter (lasted nearly ~3.5 hours!) a beautiful volunteer sitting on the right part of the desk was waiting with me to discover if she was elected in the board of that Wikimedia chapter or not. I was trying to seem relaxed in this weird situation and to feel (seem) the most calm and relaxed in the room, I started investing some time in hardening our wiki's configuration as volunteer before the planned upgrade (T268515) and that's why I was here digging in VisualEditor's REST APIs and Parsoid.

Midnight spoiler: she was elected in the board; I've found a security issue; both celebrating more volunteer workload around the corner. Yeeeh!

Anyway in short I started working from this point:

And digging VisualEditor in our semi-private wiki, it seems we are affected by an ACL issue in Parsoid.

Description of the problem

OWASP A5: it seems anonymous users can access contents of private (potentially sensitive) MediaWiki pages via Parsoid's API.

I was able to reproduce in latest MediaWiki (while I was using 1:1.35.0-1), with VisualEditor enabled and with the extension Lockdown:

I reproduced this adopting the Debian GNU/Linux MediaWiki package in buster-backports but giving an eye on the primary branch I think this issue is unrelated from that package. I say this just to remember to report the issue to its package maintainer, @Legoktm.

POC

  1. Take a random MediaWiki 1.35 with VisualEditor enabled and Lockdown (or whatever other user rights extension, I suppose)
  2. Configure your wiki to be public, but have Lockdown to have a private private, like "PrivateNamespace:"
  3. Try to access a private/sensitive page and look how wonderful is to have your protection in action:

https://example.com/wiki/PrivateNamespace:VerySecretPage
Access denied

  1. Exploit the security issue via the VisualEditor's REST API to access that private/sensitive content:

https://example.com/rest.php/testwiki.lab.reyboz.it/v3/page/html/PrivateNamespace%3AVerySecretPage
< you see the content of the private page >

Cause

I'm somehow pretty sure that the Parsoid's PageHandler#execute() at the time of writing (2020) needs a missing lookup on the PermissionManager policies.

Workaround

A quick and dirty workaround is to immediately disable VisualEditor in your private or semi-private wiki just to tighten your pants.

Another workaround is to delete every page in your wiki that contains sensitive contents.

Proposed solution

I think that in PageHandler#execute() we should introduce a lookup to the PermissionManager#userCan() method triggering the userCan hook noticed by this kind of extensions.

This is a patch I redacted for VisualEditor Parsoid's PageHandler and that fixes this issue from my perspective:

includes/VEParsoid/src/Rest/Handler/PageHandler.php
diff --git a/extension/src/Rest/Handler/PageHandler.php b/extension/src/Rest/Handler/PageHandler.php
index 8695f91dc..4bbb8c4bd 100644
--- a/extension/src/Rest/Handler/PageHandler.php
+++ b/extension/src/Rest/Handler/PageHandler.php
@@ -80,6 +80,17 @@ class PageHandler extends ParsoidHandler {
                        );
                }
 
+               // check if the user has enough privileges to see this page
+               // T270456
+               $title = Title::newFromText( $attribs['pageName'] );
+               $user = RequestContext::getMain()->getUser();
+               $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+               if( !$permissionManager->userCan( 'read', $user, $title ) ) {
+                       return $this->getResponseFactory()->createHttpError( 403, [
+                               'message' => 'Not authorized',
+                       ] );
+               }
+
                $pageConfig = $this->tryToCreatePageConfig( $attribs );
 
                if ( $format === FormatHelper::FORMAT_WIKITEXT ) {

Now.

In the meanwhile I would suggest some obvious things like:

  • invest some time in discovering how this is widespread in Parsoid
  • checkout all the Wikimedia Foundation's private or semi-private wikis (with this kind of extensions) with VisualEditor enabled
  • notify local Wikimedia chapters as well (whose wikis contain very sensitive data)
  • notify third parts through usual mailing list

I know I can't submit a Gerrit patch but let me know if I can do anything else.

Details

Risk Rating
High
Author Affiliation
Wikimedia Communities

Event Timeline

valerio.bozzolan set Security to Software security bug.
valerio.bozzolan changed the visibility from "Public (No Login Required)" to "Custom Policy".
valerio.bozzolan changed the subtype of this task from "Task" to "Security Issue".

(This is a security issue.)

I don't understand if I'm able to push my patch somewhere for review or if I can provide something more.

AFAIK for security issues it's prefered to attach/upload a git formatted patch in this access-restricted task.

@valerio.bozzolan - what @Aklapper suggested above should work fine. Here are some further instructions on generating the patch(es), which we use for Wikimedia production-affected code: https://wikitech.wikimedia.org/wiki/How_to_deploy_code#Creating_a_Security_Patch.

I'd note that this does not appear to be an issue with anything in Wikimedia production, since ext:Lockdown isn't enabled there and nothing seems to have been confirmed for any other rights-management extensions. If this remains the case, then the Security-Team wouldn't need to worry about patching production and managing this issue as any part of an upcoming security release. So the disclosure could be a bit more ad-hoc in relation to affected sites or projects.

And digging some technical debt in VisualEditor I discovered that some private and semi-private wikis

If this list could be provided on this task, we could attempt to find contacts for each of these sites/projects and work to disclose this issue, which is about as secure of a best effort as we can likely make for an issue like this. It would be even better if affected parties already had or could create a wikitech/Phab account so they could be added to this task, to review the issue and access any approved patches.

invest some time in discovering how this is widespread in Parsoid
checkout all the Wikimedia Foundation's private or semi-private wikis (with this kind of extensions) with VisualEditor enabled

This would require an extensive effort and would need to be owned by the current maintainers of VisualEditor. I'm not sure the cost-benefit here makes sense without a more granular, targeted approach. Especially if the patch posted within the task description effectively mitigates the issue in most/all circumstances.

This is a patch I redacted for VisualEditor Parsoid's PageHandler and that fixes this issue from my perspective

The patch ostensibly makes sense, but the testwiki.lab.reyboz.it URLs didn't appear to work for me - I received the same "secret" message accessing both of them. If a working patch can be provided on this task as described above, then it could also be provided as the recommended mitigation when disclosing this issue.

sbassett changed Author Affiliation from N/A to Wikimedia Communities.Jun 22 2021, 3:46 PM
sbassett changed Risk Rating from N/A to High.

Feel free to close this as declined, since at least my known stakeholders migrated away from Lockdown and completely changed their workflows to do not involve any secret in the wiki. There are private pages only for members, but just for commodity reasons. No secret is stored. So their workflows cannot involve security issues anymore.

Maybe one day MediaWiki will be ready to flexibly host secrets. But we all know this is just discouraged at the moment.

Feel free to close this as declined, since at least my known stakeholders migrated away from Lockdown and completely changed their workflows to do not involve any secret in the wiki. There are private pages only for members, but just for commodity reasons. No secret is stored. So their workflows cannot involve security issues anymore.

Maybe one day MediaWiki will be ready to flexibly host secrets. But we all know this is just discouraged at the moment.

Ok, thanks. Any reason to keep this task private in your opinion?

sbassett moved this task from Watching to Our Part Is Done on the Security-Team board.
sbassett edited projects, added SecTeam-Processed; removed Patch-For-Review.

Thanks @sbassett - I think the Status of this Task can follow the related security guidelines. I mean, feel free to open if you suggest so, also to attract more eyeballs. Wikimedia Italy adopted a different solution that does not involve any secret and does not involve Lockdown. If anybody else out of there is affected, in any case it may never resolve without opening this. Thanks.

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".Mar 4 2024, 4:58 PM