FEATURE: add support for same site cookies

Defaults to Lax, can be disabled or set to Strict.

Strict will only work if you require login and use SSO. Otherwise when clicking on links to your site you will appear logged out till you refresh the page.
This commit is contained in:
Sam 2017-02-23 12:01:28 -05:00
parent ad435da377
commit ea1007e954
5 changed files with 42 additions and 3 deletions

View File

@ -947,6 +947,7 @@ en:
email_custom_headers: "A pipe-delimited list of custom email headers"
email_subject: "Customizable subject format for standard emails. See https://meta.discourse.org/t/customize-subject-format-for-standard-emails/20801"
force_https: "Force your site to use HTTPS only. WARNING: do NOT enable this until you verify HTTPS is fully set up and working absolutely everywhere! Did you check your CDN, all social logins, and any external logos / dependencies to make sure they are all HTTPS compatible, too?"
same_site_cookies: "Use same site cookies, they eliminate all vectors Cross Site Request Forgery on supported browsers (Lax or Strict). Warning: Strict will only work on sites that force login and use SSO."
summary_score_threshold: "The minimum score required for a post to be included in 'Summarize This Topic'"
summary_posts_required: "Minimum posts in a topic before 'Summarize This Topic' is enabled"
summary_likes_required: "Minimum likes in a topic before 'Summarize This Topic' is enabled"

View File

@ -896,6 +896,14 @@ security:
force_https:
default: false
shadowed_by_global: true
same_site_cookies:
default: Lax
type: enum
choices:
- Lax
- Strict
- Disabled
regex: '^(Lax|Strict|Disabled)$'
enable_escaped_fragments: true
allow_index_in_robots_txt: true
enable_noscript_support: true

View File

@ -162,12 +162,18 @@ class Auth::DefaultCurrentUserProvider
end
def cookie_hash(unhashed_auth_token)
{
hash = {
value: unhashed_auth_token,
httponly: true,
expires: SiteSetting.maximum_session_age.hours.from_now,
secure: SiteSetting.force_https
}
if SiteSetting.same_site_cookies != "Disabled"
hash[:same_site] = SiteSetting.same_site_cookies
end
hash
end
def make_developer_admin(user)

View File

@ -10,6 +10,9 @@ class ActionDispatch::Session::DiscourseCookieStore < ActionDispatch::Session::C
if SiteSetting.force_https
cookie[:secure] = true
end
unless SiteSetting.same_site_cookies == "Disabled"
cookie[:same_site] = SiteSetting.same_site_cookies
end
end
cookie_jar(request)[@key] = cookie
end

View File

@ -143,10 +143,8 @@ describe Auth::DefaultCurrentUserProvider do
token.reload
expect(token.auth_token_seen).to eq(false)
freeze_time 21.minutes.from_now
old_token = token.prev_auth_token
unverified_token = token.auth_token
@ -222,6 +220,29 @@ describe Auth::DefaultCurrentUserProvider do
expect(UserAuthToken.where(user_id: user.id).count).to eq(2)
end
it "sets secure, same site lax cookies" do
SiteSetting.force_https = false
SiteSetting.same_site_cookies = "Lax"
user = Fabricate(:user)
cookies = {}
provider('/').log_on_user(user, {}, cookies)
expect(cookies["_t"][:same_site]).to eq("Lax")
expect(cookies["_t"][:httponly]).to eq(true)
expect(cookies["_t"][:secure]).to eq(false)
SiteSetting.force_https = true
SiteSetting.same_site_cookies = "Disabled"
cookies = {}
provider('/').log_on_user(user, {}, cookies)
expect(cookies["_t"][:secure]).to eq(true)
expect(cookies["_t"].key?(:same_site)).to eq(false)
end
it "correctly expires session" do
SiteSetting.maximum_session_age = 2
user = Fabricate(:user)