Gate the SSO password waiver on password_self_service

The waiver that lets a trusted-header session set a password without the
current one was unconditional. It is the right default — those accounts
were provisioned with a random password nobody ever saw — but an admin
who wants the current password from everybody had no way to say so.

Both call sites now go through TrustedHeaderAuth.password_self_service?,
which folds the flag into the identity check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
NeskireDK 2026-08-13 06:18:56 +02:00
parent c0a6587d52
commit fae22d037e
2 changed files with 17 additions and 3 deletions

View File

@ -23,7 +23,7 @@ module Invidious::Routes::Account
sid = sid.as(String) sid = sid.as(String)
csrf_token = generate_response(sid, {":change_password"}, HMAC_KEY) csrf_token = generate_response(sid, {":change_password"}, HMAC_KEY)
sso_verified = Invidious::TrustedHeaderAuth.asserted_email(env) == user.email sso_verified = Invidious::TrustedHeaderAuth.password_self_service?(env, user)
templated "user/change_password" templated "user/change_password"
end end
@ -52,8 +52,9 @@ module Invidious::Routes::Account
# An SSO session proves the identity through the trusted header already, so # An SSO session proves the identity through the trusted header already, so
# the current password is waived. Accounts provisioned by SSO were given a # the current password is waived. Accounts provisioned by SSO were given a
# random password the user never saw and could never type here. # random password the user never saw and could never type here. The waiver
sso_verified = Invidious::TrustedHeaderAuth.asserted_email(env) == user.email # is off when the admin turned password_self_service off.
sso_verified = Invidious::TrustedHeaderAuth.password_self_service?(env, user)
password = env.params.body["password"]? password = env.params.body["password"]?
if !sso_verified && (password.nil? || password.empty?) if !sso_verified && (password.nil? || password.empty?)

View File

@ -45,6 +45,19 @@ module Invidious::TrustedHeaderAuth
email email
end end
# Whether `user` may change their password without typing the current one.
#
# The header has to assert this very user on this very request, so a
# password-login session never qualifies. The admin can switch the waiver
# off with trusted_header_auth.password_self_service.
def password_self_service?(env, user) : Bool
Invidious::ArikSettings.password_self_service?(
CONFIG.trusted_header_auth.password_self_service,
asserted_email(env),
user.email
)
end
# Return a session id for `email`. Reuses `sid` when that session already # Return a session id for `email`. Reuses `sid` when that session already
# belongs to the user; otherwise provisions account + session and sets the # belongs to the user; otherwise provisions account + session and sets the
# SID cookie, mirroring the manual login flow (routes/login.cr). # SID cookie, mirroring the manual login flow (routes/login.cr).