Add CSRF prevention for /signout
This commit is contained in:
parent
28f564ee4c
commit
8e6bee75e7
@ -142,6 +142,11 @@ before_all do |env|
|
|||||||
user = PG_DB.query_one?("SELECT * FROM users WHERE $1 = ANY(id)", sid, as: User)
|
user = PG_DB.query_one?("SELECT * FROM users WHERE $1 = ANY(id)", sid, as: User)
|
||||||
|
|
||||||
if user
|
if user
|
||||||
|
challenge, token = create_response(user.email, "sign_out", HMAC_KEY, 1.week)
|
||||||
|
|
||||||
|
env.set "challenge", challenge
|
||||||
|
env.set "token", token
|
||||||
|
|
||||||
env.set "user", user
|
env.set "user", user
|
||||||
env.set "sid", sid
|
env.set "sid", sid
|
||||||
end
|
end
|
||||||
@ -896,21 +901,34 @@ post "/login" do |env|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Update this with using the same method for /clear_watch_history to prevent CSRF
|
|
||||||
get "/signout" do |env|
|
get "/signout" do |env|
|
||||||
|
user = env.get? "user"
|
||||||
referer = get_referer(env)
|
referer = get_referer(env)
|
||||||
|
|
||||||
|
if user
|
||||||
|
user = user.as(User)
|
||||||
|
|
||||||
|
challenge = env.params.query["challenge"]?
|
||||||
|
token = env.params.query["token"]?
|
||||||
|
|
||||||
|
begin
|
||||||
|
validate_response(challenge, token, user.email, "sign_out", HMAC_KEY)
|
||||||
|
rescue ex
|
||||||
|
error_message = ex.message
|
||||||
|
next templated "error"
|
||||||
|
end
|
||||||
|
|
||||||
|
user = env.get("user").as(User)
|
||||||
|
sid = env.get("sid").as(String)
|
||||||
|
PG_DB.exec("UPDATE users SET id = array_remove(id, $1) WHERE email = $2", sid, user.email)
|
||||||
|
|
||||||
env.request.cookies.each do |cookie|
|
env.request.cookies.each do |cookie|
|
||||||
cookie.expires = Time.new(1990, 1, 1)
|
cookie.expires = Time.new(1990, 1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if env.get? "user"
|
env.request.cookies.add_response_headers(env.response.headers)
|
||||||
user = env.get("user").as(User)
|
|
||||||
sid = env.get("sid").as(String)
|
|
||||||
PG_DB.exec("UPDATE users SET id = array_remove(id, $1) WHERE email = $2", sid, user.email)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
env.request.cookies.add_response_headers(env.response.headers)
|
|
||||||
env.redirect referer
|
env.redirect referer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -390,9 +390,9 @@ def extract_items(nodeset, ucid = nil)
|
|||||||
return items
|
return items
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_response(user_id, operation, key)
|
def create_response(user_id, operation, key, expire = 6.hours)
|
||||||
|
expire = Time.now + expire
|
||||||
nonce = Random::Secure.hex(4)
|
nonce = Random::Secure.hex(4)
|
||||||
expire = Time.now + 6.hours
|
|
||||||
|
|
||||||
challenge = "#{expire.to_unix}-#{nonce}-#{user_id}-#{operation}"
|
challenge = "#{expire.to_unix}-#{nonce}-#{user_id}-#{operation}"
|
||||||
token = OpenSSL::HMAC.digest(:sha256, key, challenge)
|
token = OpenSSL::HMAC.digest(:sha256, key, challenge)
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-u-1-4">
|
<div class="pure-u-1-4">
|
||||||
<a href="/signout?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">Sign out</a>
|
<a href="/signout?referer=<%= env.get?("current_page") %>&token=<%= env.get?("token") %>&challenge=<%= env.get?("challenge") %>" class="pure-menu-heading">Sign out</a>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">Login</a>
|
<a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">Login</a>
|
||||||
|
Loading…
Reference in New Issue
Block a user