The plugin "OATHAuth" (specifically OATHAuth-REL1_39-ae5b224.tar.gz) is vulnerable to "Emergency/Backup" TOTP reuse due to a race condition in a default configuration installation of MediaWiki 1.39
The race condition issue has led to successful re-use of the emergency/backup TOTP multiple times before that token is invalidated.
Issue was raised by email (handled by Sam Reed) and opened here for follow up.
Description
Details
- Risk Rating
- Medium
- Author Affiliation
- Other (Please specify in description)
| Status | Subtype | Assigned | Task | ||
|---|---|---|---|---|---|
| Resolved | Reedy | T325839 Release MediaWiki 1.35.10/1.38.6/1.39.3 | |||
| Resolved | Reedy | T325840 Tracking bug for MediaWiki 1.35.10/1.38.6/1.39.3 | |||
| Resolved | Security | Reedy | T330086 CVE-2023-29142: OATHAuth allows replay attacks when MediaWiki is configured without ObjectCache; Insecure Default Configuration |
Event Timeline
Similar to reported bug #T330085, this can be reproduced by the following:
1- Install MediaWiki.
2- Enable OATHAuth extension.
3-Enrol test user in MFA.
4- Obtain emergency/backup TOTP tokens during enrolment.
5- Re-use the same token by utilizing a race condition testing tool (for exmaple burp suite Turbo Intruder).
As per the discussion via email, it seems this is caused by the lack of any object cache that MediaWiki can use to temporarily store used TOTP (including scratch/emergency/recovery/backup tokens) to prevent reuse during the window till the database is updated.
The proposed fix is mostly about documentation. Update https://www.mediawiki.org/wiki/Extension:OATHAuth to include that use of ObjectCache is strongly advised. There's no README in the extension, so nothing to do there.
If we can try and highlight it in the web installer somehow too, that'd be good. That might be something worth forking to a followup task though. Maybe just an i18n message addition/update could be enough?
We may be able to issue a CVE too (it's not "insecure default permissions"; need to have a poke and see if we can find something to match). Either way, we should definitely note it in the next security update release. Should probably subtask this to T325840: Tracking bug for MediaWiki 1.35.10/1.38.6/1.39.3, and note it in T325843: Write and send release announcements for MediaWiki 1.35.10/1.38.6/1.39.3.
Trying to fix this more technically (ie so it works without ObjectCache) probably isn't feasible or sensible (like creating a DB table for "just this caching), but I also dont think OATHAuth should not work without ObjectCache (probably? Unless we want to try and fall back to something else that isn't just NullBagOfStuff... trying to use APC or something better than nothing? Obviously doesn't help in multi webserver setups, but will in a single setup, which statistically, if they haven't needed to setup caching, probably means it's a smaller wiki without many users/perf issues... But maybe it's a minor improvement).
I could attempt to try testing it again with object cache enabled but can't promise the same anytime sooner than the next two weeks.
Any specific cache setup to include in assessment?
A CVE would be nice :)
We're more than happy to request a CVE if we can find the right thing to label it as. Feel free to have a look and see if you can get something that lines up.
Regarding the caching, it shouldn't matter too much what you use... I've no idea what OS you're running MW on, but happy to advise further - https://www.mediawiki.org/wiki/Manual:Performance_tuning#Main_cache and using APC or Memcached should be more than enough (you can use the database too, but as we're talking about race conditions, it'd likely be slower too).
There's no massive rush, I don't think. The caching is definitely a key part, even if enabling it doesn't fix the issue completely. Documentation updates on the wiki can be done seperately, and without referencing this task/security issue, so don't really need to wait for that.
If a cache is absolutely needed, ObjectCache::getLocalServerInstance( CACHE_ANYTHING ) will first try APCu, then any other configured cache, and then CACHE_DB (if it's usable) before returning a NullBagOStuff.
EmptyBagOStuff is what we both meant.
Defaulting to APCu in the case where it's >1 server isn't helpful... But if we checked if MediaWikiServices::getInstance()->getMainObjectStash() instanceof EmptyBagOStuff, and then called ObjectCache::getLocalServerInstance( CACHE_ANYTHING ) (doesn't look to be exposed via MediaWikiServices?) if it is a EmptyBagOStuff as the fallback to at least try some other options...
That does feel like an improvement on the current state of affairs?
index 336083f..9e61be4 100644 --- a/src/Key/TOTPKey.php +++ b/src/Key/TOTPKey.php @@ -21,6 +21,7 @@ namespace MediaWiki\Extension\OATHAuth\Key; use Base32\Base32; use DomainException; +use EmptyBagOStuff; use Exception; use jakobo\HOTP\HOTP; use MediaWiki\Extension\OATHAuth\IAuthKey; @@ -29,6 +30,7 @@ use MediaWiki\Extension\OATHAuth\OATHUserRepository; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MWException; +use ObjectCache; use Psr\Log\LoggerInterface; /** @@ -143,6 +145,12 @@ class TOTPKey implements IAuthKey { // Prevent replay attacks $store = MediaWikiServices::getInstance()->getMainObjectStash(); + + if ( $store instanceof EmptyBagOStuff ) { + // Try and find some usable cache if the MainObjectStash isn't useful + $store = ObjectCache::getLocalServerInstance( CACHE_ANYTHING ); + } + $uid = MediaWikiServices::getInstance() ->getCentralIdLookupFactory() ->getLookup()
https://cwe.mitre.org/data/definitions/362.html
This is the closest CWE mapping to race conditions.
+1 to @Reedy's patch above. Could this just get pushed through gerrit as an OATHAuth "performance improvement" with a benign commit message?
Change 890915 had a related patch set uploaded (by Reedy; author: Reedy):
[mediawiki/extensions/OATHAuth@master] TOTPKey: Add better fallback attempts to find a useable cache
Change 890915 merged by jenkins-bot:
[mediawiki/extensions/OATHAuth@master] TOTPKey: Add better fallback attempts to find a useable cache
Change 890853 had a related patch set uploaded (by Reedy; author: Reedy):
[mediawiki/extensions/OATHAuth@REL1_39] TOTPKey: Add better fallback attempts to find a useable cache
Change 890854 had a related patch set uploaded (by Reedy; author: Reedy):
[mediawiki/extensions/OATHAuth@REL1_38] TOTPKey: Add better fallback attempts to find a useable cache
Change 890855 had a related patch set uploaded (by Reedy; author: Reedy):
[mediawiki/extensions/OATHAuth@REL1_35] TOTPKey: Add better fallback attempts to find a useable cache
Change 890853 merged by jenkins-bot:
[mediawiki/extensions/OATHAuth@REL1_39] TOTPKey: Add better fallback attempts to find a useable cache
Change 890854 merged by jenkins-bot:
[mediawiki/extensions/OATHAuth@REL1_38] TOTPKey: Add better fallback attempts to find a useable cache
Change 890855 merged by jenkins-bot:
[mediawiki/extensions/OATHAuth@REL1_35] TOTPKey: Add better fallback attempts to find a useable cache
Likely Incorrect Access Controls or Insecure Permissions for the vulnerability type. Or possibly just Other. The attack type is Remote and the Impact would be Escalation of Privileges and Information Disclosure.
As the ostensible "vendors" of the MediaWiki extension, we would typically request them just prior to our quarterly security release.
@MajidAlqabandi as per our original discussion, I've now updated the onwiki documentation for the extension to advise people to setup caching when using it - https://www.mediawiki.org/w/index.php?title=Extension%3AOATHAuth&diff=5851727&oldid=5843636&diffmode=source
Let me know if you think that's enough, and for example, in your case, if that would've encouraged you to setup caching (which would have prevented this issue in the edge case). Obviously with the hardening patch tagged.
Wording can be improved/changed later, of course. But that's hopefully an improvement...
@Reedy Fair enough, I was thinking if someone would like to read more on the topic, perhaps mentioned this TT?
Just thinking out loud on how to educate people on race conditions.
We can, but most people probably don’t care.
When it’s public we can indeed link it for reference.
We can, but most people probably don’t care.
When it’s public we can indeed link it for reference.
@MajidAlqabandi guessing you want crediting on https://security.wikimedia.org/hall-of-fame/ ? :)
@Reedy Can we disclose?
Am working on a blog post for this and wanted to check first. Also, would love to be listed in the HoF :)
Change 923570 had a related patch set uploaded (by SBassett; author: SBassett):
[wikimedia/security/landing-page@master] Add Majid Alqabandi to Security Team Hall of Fame
Change 923570 merged by jenkins-bot:
[wikimedia/security/landing-page@master] Add Majid Alqabandi to Security Team Hall of Fame
Change 923572 had a related patch set uploaded (by SBassett; author: SBassett):
[wikimedia/security/landing-page@master] Add Majid Alqabandi to Security Team Hall of Fame (build step)
Change 923572 merged by jenkins-bot:
[wikimedia/security/landing-page@master] Add Majid Alqabandi to Security Team Hall of Fame (build step)
@MajidAlqabandi - You've officially made the hall of fame, congratulations: https://security.wikimedia.org/hall-of-fame/