User tests: Successful: Unsuccessful:
Pull Request resolves # .
Replace md5(secret . seed) with hash_hmac('sha256', $seed, $secret) in
ApplicationHelper::getHash().
This method generates CSRF form tokens, user activation tokens, and password
reset tokens. The previous implementation used MD5 (broken since 2004, RFC 6151)
with plain concatenation, which is vulnerable to length extension attacks.
HMAC-SHA256 (RFC 2104) is the correct construction for keyed hashing.
Run the new unit test:
vendor/bin/phpunit tests/Unit/Libraries/Cms/Application/ApplicationHelperTest.php
All 5 tests should pass. No functional changes — tokens are generated fresh
at runtime so no migration is needed.
getHash() returns md5($secret . $seed) — a 32-char hex string using broken MD5.
getHash() returns hash_hmac('sha256', $seed, $secret) — a 64-char hex string
using HMAC-SHA256, resistant to length extension attacks.
Please select:
| Status | New | ⇒ | Pending |
| Category | ⇒ | Libraries Unit Tests |
| Labels |
Added:
Unit/System Tests
PR-5.4-dev
|
||
| Status | Pending | ⇒ | Closed |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2026-05-27 17:20:41 |
| Closed_By | ⇒ | Hackwar |
Hello @ManhThuan, I understand what you are trying to do here, unfortunately this is a hard backwards compatibility break. It is such a hard b/c break, that we wont be adding this to Joomla. Yes, MD5 is broken, but contrary to what the method claims, it also does not return a secure hash in any way, shape or form. This method is used to name several identifiers for cookies, etc. and if we merge your proposal, it would mean that for example all sessions and all cookie consents would be invalidated. Besides that, the length of the hash changes as well and we have to assume that there are several cases where this is used with fixed-length database columns or string checks. If you want to provide HMAC-SHA256, you would have to provide a new method, but we still couldn't switch the usage in our code to use that new method because of the above reasons.
For these reasons, I'm closing this PR. Thank you for your work, but unfortunately we wont be able to accept this. We would be happy if you would contribute again in the future.