summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Roth <omarroth@hotmail.com>2018-11-08 17:42:25 -0600
committerOmar Roth <omarroth@hotmail.com>2018-11-08 17:42:25 -0600
commit8e6bee75e7b79a58a7db66c4763e5eead20bb90f (patch)
tree803cbb78668f951d986526e9f18c4ad58a5091ed
parent28f564ee4c1b188c06d91d3e4ca0412dd121ad12 (diff)
downloadinvidious-8e6bee75e7b79a58a7db66c4763e5eead20bb90f.tar.gz
invidious-8e6bee75e7b79a58a7db66c4763e5eead20bb90f.tar.bz2
invidious-8e6bee75e7b79a58a7db66c4763e5eead20bb90f.zip
Add CSRF prevention for /signout
-rw-r--r--src/invidious.cr26
-rw-r--r--src/invidious/helpers/helpers.cr4
-rw-r--r--src/invidious/views/template.ecr2
3 files changed, 25 insertions, 7 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 867a70d3..7c2b224b 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -142,6 +142,11 @@ before_all do |env|
user = PG_DB.query_one?("SELECT * FROM users WHERE $1 = ANY(id)", sid, as: 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 "sid", sid
end
@@ -896,21 +901,34 @@ post "/login" do |env|
end
end
-# TODO: Update this with using the same method for /clear_watch_history to prevent CSRF
get "/signout" do |env|
+ user = env.get? "user"
referer = get_referer(env)
- env.request.cookies.each do |cookie|
- cookie.expires = Time.new(1990, 1, 1)
+ 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
- if env.get? "user"
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|
+ cookie.expires = Time.new(1990, 1, 1)
end
env.request.cookies.add_response_headers(env.response.headers)
+ end
+
env.redirect referer
end
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 46b2c7b7..877a9d32 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -390,9 +390,9 @@ def extract_items(nodeset, ucid = nil)
return items
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)
- expire = Time.now + 6.hours
challenge = "#{expire.to_unix}-#{nonce}-#{user_id}-#{operation}"
token = OpenSSL::HMAC.digest(:sha256, key, challenge)
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index 1e31fb4a..a6191d36 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -67,7 +67,7 @@
</a>
</div>
<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>
<% else %>
<a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">Login</a>