FEATURE: Flag to disable DiscourseConnect CSRF protection (#12356)

This is not recommended. But if you have other protections in place for CSRF mitigation, you may wish to disable Discourse's implementation. This site setting is not visible in the UI, and must be changed via the console.
This commit is contained in:
David Taylor
2021-03-11 10:38:34 +00:00
committed by GitHub
parent 593edc43c5
commit 0902e56162
3 changed files with 40 additions and 4 deletions

View File

@ -31,21 +31,37 @@ class DiscourseSingleSignOn < SingleSignOn
def register_nonce(return_path) def register_nonce(return_path)
if nonce if nonce
@secure_session.set(nonce_key, return_path, expires: SingleSignOn.nonce_expiry_time) if SiteSetting.discourse_connect_csrf_protection
@secure_session.set(nonce_key, return_path, expires: SingleSignOn.nonce_expiry_time)
else
Discourse.cache.write(nonce_key, return_path, expires_in: SingleSignOn.nonce_expiry_time)
end
end end
end end
def nonce_valid? def nonce_valid?
nonce && @secure_session[nonce_key].present? if SiteSetting.discourse_connect_csrf_protection
nonce && @secure_session[nonce_key].present?
else
nonce && Discourse.cache.read(nonce_key).present?
end
end end
def return_path def return_path
@secure_session[nonce_key] || "/" if SiteSetting.discourse_connect_csrf_protection
@secure_session[nonce_key] || "/"
else
Discourse.cache.read(nonce_key) || "/"
end
end end
def expire_nonce! def expire_nonce!
if nonce if nonce
@secure_session[nonce_key] = nil if SiteSetting.discourse_connect_csrf_protection
@secure_session[nonce_key] = nil
else
Discourse.cache.delete nonce_key
end
end end
end end

View File

@ -475,6 +475,9 @@ login:
discourse_connect_overrides_website: false discourse_connect_overrides_website: false
discourse_connect_overrides_card_background: false discourse_connect_overrides_card_background: false
discourse_connect_not_approved_url: "" discourse_connect_not_approved_url: ""
discourse_connect_csrf_protection:
default: true
hidden: true
blocked_email_domains: blocked_email_domains:
default: "mailinator.com" default: "mailinator.com"
type: list type: list

View File

@ -375,10 +375,27 @@ describe DiscourseSingleSignOn do
sso = DiscourseSingleSignOn.parse(payload, secure_session: secure_session) sso = DiscourseSingleSignOn.parse(payload, secure_session: secure_session)
expect(sso.nonce_valid?).to eq true expect(sso.nonce_valid?).to eq true
other_session_sso = DiscourseSingleSignOn.parse(payload, secure_session: SecureSession.new("differentsession"))
expect(other_session_sso.nonce_valid?).to eq false
sso.expire_nonce! sso.expire_nonce!
expect(sso.nonce_valid?).to eq false expect(sso.nonce_valid?).to eq false
end
it "allows disabling CSRF protection" do
SiteSetting.discourse_connect_csrf_protection = false
_ , payload = DiscourseSingleSignOn.generate_url(secure_session: secure_session).split("?")
sso = DiscourseSingleSignOn.parse(payload, secure_session: secure_session)
expect(sso.nonce_valid?).to eq true
other_session_sso = DiscourseSingleSignOn.parse(payload, secure_session: SecureSession.new("differentsession"))
expect(other_session_sso.nonce_valid?).to eq true
sso.expire_nonce!
expect(sso.nonce_valid?).to eq false
end end
it "generates a correct sso url" do it "generates a correct sso url" do