Fix an open redirect exploit where if you went to <https://danbooru.donmai.us/login?url=//fakebooru.com>, then after you logged in you would be redirected to https://fakebooru.com. This was actually fixed by the upgrade to Rails 7.0. `redirect_to` now raises an `UnsafeRedirectError` on redirect to an offsite URL. Before we tried to prevent offsite redirects by checking that the URL started with a slash, but this was insufficient - it allowed protocol-relative URLs like `//fakebooru.com`. Add a test case for protocol-relative URLs and return a 403 error on an offsite redirect.
38 lines
831 B
Ruby
38 lines
831 B
Ruby
# frozen_string_literal: true
|
|
|
|
class SessionsController < ApplicationController
|
|
respond_to :html, :json
|
|
skip_forgery_protection only: :create, if: -> { !request.format.html? }
|
|
|
|
rate_limit :create, rate: 1.0/1.minute, burst: 10
|
|
|
|
def new
|
|
@user = User.new
|
|
end
|
|
|
|
def confirm_password
|
|
end
|
|
|
|
def create
|
|
name, password, url = params.fetch(:session, params).slice(:name, :password, :url).values
|
|
user = SessionLoader.new(request).login(name, password)
|
|
url ||= posts_path
|
|
|
|
if user
|
|
respond_with(user, location: url)
|
|
else
|
|
flash.now[:notice] = "Password was incorrect"
|
|
raise SessionLoader::AuthenticationFailure
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
SessionLoader.new(request).logout
|
|
redirect_to(posts_path, :notice => "You are now logged out")
|
|
end
|
|
|
|
def sign_out
|
|
destroy
|
|
end
|
|
end
|