Security issues with authorization extensions

MediaWiki is not designed to be a Content Management System (CMS), or to protect sensitive data. To the contrary, it was designed to be as open as possible. Thus it does not inherently support full featured, air-tight protection of private content. But with the massive increase of MediaWiki use in corporate intranets and the many CMS-like features emerging, demand for tighter security is emerging.

To help authors of security extensions, this list of the security flaws found in the field is being maintained, so that they can test their extension against each. There are several extensions that claim to give selective read/write access to pages in Category:Page specific user rights extensions , and currently most of these do exhibit several of the listed flaws.

Testing security extensions

If you are going to implement read or write access, check the extension for the flaws listed in the table below by logging in as a user without read/write permissions. Starting a new web browsing session via incognito mode allows for site navigation as an unprivileged user as the software is tested and configured.

Table of common security extension limitations

Function/Test Check for Comment
Inclusion/transclusion
  • Can you access restricted pages via {{:restricted article}}? What if you use multiple levels (transclusions within transclusions)?
  • Can you access restricted pages via a transclusion to a redirection?
  • Can you circumvent a transclusion restriction by using the transclusion in edit preview mode or via Special:ExpandTemplates?
  • Can you circumvent a transclusion restriction by using the API (e.g. the action=parse method)
  • Can you use error messages that take user controlled parameters and then parse them as wikitext, to circumvent restrictions
  • Can you access via {{msgnw::Page Name}}
This is partially addressed by the $wgNonincludableNamespaces setting introduced in MW 1.10 (rev:19934). You can also use manual:Hooks/BeforeParserFetchTemplateAndtitle , ParserOptions::setTemplateCallback(), ParserOptions::setCurrentRevisionCallback() but be careful of caching.
Preloading
  • Can you circumvent the restriction using editintro= or preload= URI parameters in edit mode?
Should be safe with extension using the UserCan hook, at least since 1.12 (maybe also earlier).
XML export (Special:Export)
  • Is it possible to export the contents of a restricted page?
For extensions using the userCan hook, this has been fixed in MW 1.10 (rev:19935).
Atom/RSS feeds
  • Does the article get delivered? With diff or full content?
    There are two feeds, one in the Recent changes special pages and other on the page history. Additional feeds may be provided by extensions.
For extensions using the userCan hook, this has been fixed in MW 1.12 (rev:25944). userCan is not honored in MW 1.14 and definitely earlier (SpecialRecentChanges*.php got moved)! RecentChanges pages lists edit comments.
Listings & search
  • are non-readable pages listed on the Special:Search page? Are excerpts shown? (See also phab:T10825)
  • are non-readable pages listed on Special:Recentchanges or Special:Allpages?
  • are non-readable pages listed on other special pages, such as Lonelypages, etc?
For extensions using the userCan hook, this has been partially addressed in MW 1.10 (rev:21821): The search page no longer shows excerpts from pages that are not readable - but it still lists the titles of articles which are not accessable to the user.
Diff & revision links
  • Can a direct link to a page diff be used to show text from a restricted page? How about a diff between a revision of an unrestricted and a revision of a restricted page, by manipulating the revision IDs?
  • Can you use a permanent link (revision link) to an old version to read a page you shouldn't read? How about a link that has a revision ID belonging to a different than the title refers to, by manipulating the URL?
For extensions using the userCan hook, this should be OK on recent versions of MediaWiki.
API
  • Can the revids parameter for action=query be used to fetch revisions that should be hidden?
  • Can action=compare leak the page contents.
In modern MediaWiki, a userCan hook should get the prop=revisions case, but maybe not others
Action links
  • Can you use action=raw or action=render options to read a page you shouldn't read?
  • Can you access a printable version of a page you shouldn't read?
  • Can a direct link to the edit page be used to view page contents of a restricted page?
For extensions using the userCan hook, this should be OK on recent versions of MediaWiki.
Related rights
  • Does the extension prevent a user from creating a new page that they won't have read access to?
  • Can you move or rename a page that you have read access to but not write access to?
  • Can you read a discussion page of a page you don't have read access to? Can you write a discussion page of a page you don't have write access to, unless this is specifically allowed by you?
If using userCan, this should be OK, but might need to write ArticleInsertComplete hook for creations and TitleMoveComplete hook for moves that call userCan to 'copy' permissions.
Author backdoor
  • Some extensions always allow the original author of a page to access it, ignoring later access restrictions.
Caching
  • Parser cache (enabled by default) caches articles between users.
  • $wgEnableSidebarCache (not enabled by default) performs a similar function for the sidebar. If the extension could send different pages to different users, it might be incompatible with this caching.
Limiting article caching to anonymous users might provide most of the performance benefits for sites with mostly anonymous users (like Wikipedia), without compromising security.
Files & Images
  • Can you download a file directly regardless of read access to its associated article?
  • Can you download a thumbnail of an image file directly regardless of read access to its associated article?
  • Can you upload or delete an image regardless of write access to its associated article?
Since uploaded files are normally served directly by the web server, not through MediaWiki, it's not easily possible for extensions to prevent access. See Manual:Image Authorisation for instructions on setting up access restrictions for images. (img_auth.php uses userCan since r52751).
−Redirects
  • If a user has permission to view a redirect but not the page it points to, are they still redirected?
  • If a user has permission to view a page but not a redirect that points to that page, can they access the page via the redirect?
Edit Section
  • Can a user use the 'edit section' feature for a page, even though they can't edit the full page (either through the interface or by changing the URL)?
  • Can a user use the 'edit section' feature for pages they have been granted access to?
If the security relies on tags embedded in the page code then these tags will not necessarily be present in the text you are editing, even if they are present elsewhere on the page.
Watching Pages
  • Can a user watch a page they are not allowed to read?
  • Can the user unwatch a page they are not allowed to read?
  • Does the user still get notifications even if they were locked out?
Needs a WatchArticle hook that will call userCan.
Other extensions
  • Can a user use other extensions to view part of a page? Think of DynamicPageList or Semantic MediaWiki , which provide ways to query the database for certain pages or properties.
  • Does an extension display confidential page titles, like a recently-edited page gadget?
  • Can you retrieve the contents of a page via Scribunto's mw.title.new( "Page name" )::getContent()

Scribunto will respect ParserOptions::setCurrentRevisionCallback revision fetching callbacks, but other extensions probably won't

Cache pollution

Is there any situation where a private page could get cached by MediaWiki, with the permission checked at cache time. Then later on, another user gets the cached value without the permission check being run.

API:REST API
  • Does the REST API display confidential pages?
Activated when VisualEditor or some other extensions are activated.

There are probably more "holes" in the read protection system. So, denying read access should be seen as a "nothing to see here, move along," sort of thing rather than a guarantee of secrecy.