Use the IPAddr library to detect ipv4 and ipv6 addresses
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled

This commit is contained in:
Dan Milne
2025-10-29 13:47:02 +11:00
parent d96a864436
commit 54025917de
6 changed files with 762 additions and 30 deletions

View File

@@ -16,9 +16,10 @@ class SessionsController < ApplicationController
return
end
# Store the redirect URL from forward auth if present
# Store the redirect URL from forward auth if present (after validation)
if params[:rd].present?
session[:return_to_after_authenticating] = params[:rd]
validated_url = validate_redirect_url(params[:rd])
session[:return_to_after_authenticating] = validated_url if validated_url
end
# Check if user is active
@@ -35,9 +36,10 @@ class SessionsController < ApplicationController
if user.totp_enabled?
# Store user ID in session temporarily for TOTP verification
session[:pending_totp_user_id] = user.id
# Preserve the redirect URL through TOTP verification
# Preserve the redirect URL through TOTP verification (after validation)
if params[:rd].present?
session[:totp_redirect_url] = params[:rd]
validated_url = validate_redirect_url(params[:rd])
session[:totp_redirect_url] = validated_url if validated_url
end
redirect_to totp_verification_path(rd: params[:rd])
return
@@ -115,4 +117,33 @@ class SessionsController < ApplicationController
session.destroy
redirect_to profile_path, notice: "Session revoked successfully."
end
private
def validate_redirect_url(url)
return nil unless url.present?
begin
uri = URI.parse(url)
# Only allow HTTP/HTTPS schemes
return nil unless uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
# Only allow HTTPS in production
return nil unless Rails.env.development? || uri.scheme == 'https'
redirect_domain = uri.host.downcase
return nil unless redirect_domain.present?
# Check against our ForwardAuthRules
matching_rule = ForwardAuthRule.active.find do |rule|
rule.matches_domain?(redirect_domain)
end
matching_rule ? url : nil
rescue URI::InvalidURIError
nil
end
end
end