Conversation
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
left a comment
There was a problem hiding this comment.
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 Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Why do this? |
Security by obscurity I think |
|
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. |
|
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? |
|
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. |
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_secretand 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.