Skip to content

Do not expose the phpMyAdmin version in asset URLs - #20432

Open
pongoe wants to merge 1 commit into
phpmyadmin:masterfrom
pongoe:hide-version-in-asset-urls-15993
Open

pongoe wants to merge 1 commit into
phpmyadmin:masterfrom
pongoe:hide-version-in-asset-urls-15993

Conversation

@pongoe

@pongoe pongoe commented Aug 20, 2026

Copy link
Copy Markdown

Fixes #15993

Right now every CSS and JS asset gets loaded with ?v=<version> as a cache buster, so anyone who can reach the login page can read the exact phpMyAdmin version straight out of the page source (32 places on the login page alone).

This swaps the version for an opaque token: an HMAC-SHA256 of the version, keyed with the configured blowfish_secret and trimmed to 12 hex characters. It still changes on every upgrade, so cache busting keeps working exactly like it does today, but there's no way to map it back to a version with a lookup table. If no blowfish secret is configured, it falls back to a random per-session key, so it never turns into a hash anyone could compute for themselves.

Every CSS and JS asset was loaded with ?v=<version> for cache busting, and the
version was also passed to JavaScript in CommonParams. Both are sent to
unauthenticated visitors on the login page.

Replace the version with an opaque token from Config::getAssetVersion(): the
first 12 hex chars of hash_hmac('sha256', Version::VERSION, blowfish_secret).
It still changes on every upgrade, so cache busting and the "reload scripts
from another version" check in ajax.ts keep working, but it cannot be mapped
back to a version.

pma.version stays available in Twig for the home page, which is only shown
after login.

Fixes phpmyadmin#15993

Signed-off-by: Pongoe <pongoe@users.noreply.github.com>

@williamdes williamdes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it, but I think it is important to note that there is many many ways to know what version you are running. With some hours on my hands I can do guessing and get accurate on most versions. Since a lot of them change the CSS, just grep a class and you will know

@codecov

codecov Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.77%. Comparing base (527e795) to head (a5bb7f3).
⚠️ Report is 8613 commits behind head on master.

Additional details and impacted files
@@              Coverage Diff              @@
##             master   #20432       +/-   ##
=============================================
+ Coverage     50.55%   63.77%   +13.21%     
+ Complexity    17244    16127     -1117     
=============================================
  Files           607      676       +69     
  Lines         68783    58026    -10757     
=============================================
+ Hits          34773    37005     +2232     
+ Misses        34010    21021    -12989     
Flag Coverage Δ
dbase-extension 63.76% <100.00%> (+13.59%) ⬆️
guzzlehttp/psr7-psr-7 ?
laminas/laminas-diactoros-psr-7 ?
nyholm/psr7-psr-7 ?
recode-extension ?
slim/psr7-psr-7 ?
unit-7.2-ubuntu-latest ?
unit-7.3-ubuntu-latest ?
unit-7.4-ubuntu-latest ?
unit-8.0-ubuntu-latest ?
unit-8.1-ubuntu-latest ?
unit-8.2-ubuntu-latest 63.73% <100.00%> (+14.18%) ⬆️
unit-8.3-ubuntu-latest 63.71% <100.00%> (+13.40%) ⬆️
unit-8.4-ubuntu-latest 63.73% <100.00%> (+14.19%) ⬆️
unit-8.5-ubuntu-latest 63.71% <100.00%> (+14.18%) ⬆️
unit-8.6-ubuntu-latest ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kamil-tekiela

Copy link
Copy Markdown
Contributor

Why do this?

@williamdes

Copy link
Copy Markdown
Member

Why do this?

Security by obscurity I think

@pongoe

pongoe commented Aug 20, 2026

Copy link
Copy Markdown
Author

It came out of #15993. The main problem is that the version string in asset URLs sits in the page source of the login page, which gets indexed. So when a CVE lands for a specific version, you can find vulnerable installs with a Google search. A determined attacker can still fingerprint the build by other means, but this takes installs out of that easy dragnet. Cache busting still works the same since the token still changes on every upgrade.

@kamil-tekiela

Copy link
Copy Markdown
Contributor

I see, so the goal is to make it harder for attackers to find vulnerable publicly accessible installs. From my point of view, having phpMyAdmin installed on a production server is a security issue in itself. Running a vulnerable version is even worse. So this is definitely security by obscurity. We won't provide any more security to the users by doing this, but we can make it a tiny bit harder for attackers. But is this really the best way to do it?

@pongoe

pongoe commented Aug 20, 2026

Copy link
Copy Markdown
Author

You're right, it doesn't add any security in itself. It is security by obscurity, and I'd call it good practice rather than essential.

What it removes is the script kiddie with a Google dork finding vulnerable installs. But you're dead right. Having phpMyAdmin installed on a production server is just asking for trouble. But of course, that's what plenty of people do ...

As for whether it's the best way, I'd say it works. Anything stronger gets into whether unauthenticated visitors should be served assets at all, which felt out of scope here. If you had a different approach in mind, I'm happy to look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

do not expose PMA_VERSION in requests

4 participants