Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
phpmyadmin-config-set-2fa — phpMyAdmin 5.2.3 - High - Remote - 2FA - config/set clears two-factor | Kitploit
Tools/GitHubGitHub/abraxas/phpmyadmin-config-set-2fa
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingAuthenticationLabs & Practice
GitHubabraxas/phpmyadmin-config-set-2fa

phpmyadmin-config-set-2fa

phpMyAdmin 5.2.3 - High - Remote - 2FA - config/set clears two-factor

View Repository
94 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - phpmyadmin-config-set-2fa

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  phpmyadmin-config-set-2fa

phpmyadmin-config-set-2fa

Class: Privilege leftover / missing step-up Reach: Remote

phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin

POST index.php?route=/config/set writes any allowlisted preference, including 2fa. UserPreferences::persistOption does no validation. Settings -> Two-factor still calls TwoFactor::check(true) before it will drop the factor. /config/set does not.

A logged-in session, or XSS/CSRF that can POST the page token, can send key=2fa and value=null. The next password login has no TOTP, WebAuthn, or Simple prompt. Durable strip, not a one-request skip.

IDno CVE yet
ClassPrivilege leftover / missing step-up
ReachRemote (authenticated cookie login; CSRF token required)
CWECWE-620
CVSSHigh: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
ProductphpMyAdmin
Affected5.2.3 tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
Authcookie login. CSRF token required. Completes XSS or CSRF to a durable 2FA strip
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only

What an attacker can do

Strip 2FA from a phpMyAdmin account without presenting TOTP, WebAuthn, or the Simple confirm field. The next password login is password-only. Full PMA as that MySQL user (SQL, users, export).

PrivilegeMethod / pathRecon / integrity / availabilityLab-proven or inferred
Persist 2fa to null and drop the second factor from pmadbAuthenticated POST index.php?route=/config/set key=2fa value=null plus a valid tokenIntegrity of the preference storeLab-proven. success:true, pmadb config_data became []
Log in with password only after that writeNew cookie session, same MySQL userIntegrity of the login pathLab-proven. No 2fa_confirm, landed in the normal UI
Keep the current session while 2FA disappears for later loginsSame handler; persistOption writes the store, not the live two_factor_check flagIntegrity of later sessionsLab-proven. Session A stayed in. Session B had seen 2FA. Session C did not
Chain from stored XSS or CSRF that can POST with the page tokenSame-review leftovers, not this labIntegrity of 2FA after a same-origin POSTInferred
Remove 2FA through SettingsPOST /preferences/two-factor 2fa_remove=1Integrity of 2FA via the documented UILab-proven closed. Without the factor, PMA shows the confirm page and pmadb still has backend=simple

Closed on this leftover: unauthenticated access, skipping the MySQL password, OS RCE, reading other users' pmadb rows. I did not need leftover #1 (CustomServer signature). I did not skip the MySQL password.

Same pin: WebAuthn CustomServer leftover.

How I found it

I pinned 5.2.3 after PMASA-2025-1/2/3. Cookie auth, pmadb pma__userconfig. The lab turns on $cfg['DBG']['simple2fa'] only so Settings can enroll the Simple backend without a hardware key. TOTP and WebAuthn live in the same 2fa preference key.

SetConfigController takes key and JSON value and calls Config::setUserValue. UserPreferences::persistOption is documented "No validation is done!" apply() allowlists 2fa so the key is not dropped as an unknown pref.

$result = $this->config->setUserValue(null, $key, json_decode($value));

json_decode('null') is PHP null. persistOption('2fa', null, $default) then unsets config_data['2fa'] because the default for that path is also null.

Settings -> Two-factor is the contrast. TwoFactorController will not configure('') until TwoFactor::check(true) returns true.

Wrong turns already recorded: treating Settings 2fa_remove as the hole (it still demands the factor); claiming unauthenticated access; claiming a skip of the MySQL password; treating this as leftover #1 (CustomServer); a reverse shell. Theatre.

Lab

python3 phpmyadmin-config-set-2fa-Abraxas-Labs.py
# or: cd lab && ./run.sh

Target only http://127.0.0.1:19280. Compose project phpmyadmin-config-set-2fa. Pin RELEASE_5_2_3. run.sh copies or clones that tag into lab/src/ for the image. Stack tears down after the run.

Settings enrolled Simple 2FA. A second browser hit the 2fa_confirm page. POST 2fa_remove without the factor stayed on the confirm UI and left backend=simple in pmadb. POST /config/set then returned success:true, pmadb became [], and the next login landed in the normal UI.

SUCCESS phpmyadmin-config-set-2fa enroll=simple ui-remove-blocked=yes config-set-cleared=yes next-login-password-only=yes PMA-CONFIG-SET-2FA-WITNESS

The fix

Deny 2fa (and other auth keys) on /config/set. Require TwoFactor::check(true) before any 2FA mutation. Keep the Settings path as the only writer.

References

  • github.com/phpmyadmin/phpmyadmin tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
  • libraries/classes/Controllers/Config/SetConfigController.php
  • libraries/classes/Config/UserPreferences.php
  • Same pin: PMA-5.2.3-WebAuthn-2FA
  • CWE-620

License

GNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.

Download Tool