fix: scope MD5 PASSWORD_HASHERS override to test runs only#1096
fix: scope MD5 PASSWORD_HASHERS override to test runs only#1096mgradalska wants to merge 1 commit into
Conversation
The previous predicate (`"karrio" in _sys.argv[0]`) matches the install path of the `karrio` virtualenv (`/karrio/venv/bin/gunicorn`), so the test-only MD5 PASSWORD_HASHERS override was firing in production gunicorn workers as well. Two consequences for any deployment upgraded past 2026.1.22: - Pre-upgrade users with PBKDF2-hashed passwords can no longer log in, because the loaded hasher list cannot verify their hash format. - New users (createsuperuser, dashboard signup) have their passwords stored as MD5, which Django itself documents as test-only. Replace the argv-based predicate with a custom TEST_RUNNER subclass that sets PASSWORD_HASHERS in `setup_test_environment`. Django loads TEST_RUNNER only for `manage.py test` / `karrio test`, so the override fires exactly when intended and never touches production process state. refs https://github.com/orgs/karrioapi/discussions/1094
|
@mgradalska is attempting to deploy a commit to the karrio Team on Vercel. A member of the Team first needs to authorize it. |
|
Getting the dev environment setup is a bit daunting, but the docs here are the current ones afaik and using the Nice to see more PRs imo 🫂 #1094 If It was me... I'd wonder if anything would need to be done from a data standpoint for systems that might have gotten some messed up users in the interim... or if we just trust those users to be able to re-setup the users which have the wrong hashing...? |
|
FYI I used sudo docker exec -it karrio.db psql -U postgres -d db -c "
select email, is_staff, is_superuser, is_active, left(password, 80) as password_prefix
from \"user_user\"
order by email;
"To 'see' the hash used for the existing passwords to help me debug after upgrading without this PR and also not being able to login -- I saw Thanks for the save mgradalska! Hopefully it'll get merged soon so others don't have the same struggle. |
|
@ChrisNolan Honestly, I don't think there's a clean automated remediation worth shipping here. Anything we'd do (force reset, append MD5 as a verifier, etc.) is an operator-policy call rather than a library decision. For my own deployment I just created a fresh user once we hit this - that was an acceptable solution in my case. But I imagine this can be quite problematic for anyone with lots of users - for those A note in the changelog calling out that user passwords created on |
refs https://github.com/orgs/karrioapi/discussions/1094
Bug
After upgrading past
2026.1.22, existing users can't log in to the dashboard, and new users have their passwords stored as MD5.Root Cause
The test-only
PASSWORD_HASHERSoverride in [settings/base.py](https://github.com/karrioapi/karrio/blob/main/apps api/karrio/server/settings/base.py#L377-L383) (added in 2026.1.22, commitf19fe206e) fires in production because its second predicate matches the install path:In
karrio/server, gunicorn'ssys.argv[0]is/karrio/venv/bin/gunicorn- which contains "karrio". The override fires unconditionally.Fix
Replace the argv predicate with a custom
TEST_RUNNERthat setsPASSWORD_HASHERSinsetup_test_environment. Django loadsTEST_RUNNERonly duringkarrio test(the test management command), so production is never affected and the test-suite perf win fromf19fe206eis preserved.Tests
Couldn't run the full suite locally. Relying on this PR's
karrio-testsworkflow.Notes
Already MD5-hashed users (created on any
2026.1.22+deploy) will be locked out by this fix the same way PBKDF2 users were locked out by the original bug. Worth shipping a release that appendsMD5PasswordHashertoPASSWORD_HASHERS.