You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wi...@apache.org on 2020/01/14 11:45:38 UTC
[couchdb] 02/02: Add SameSite support to auth cookie
This is an automated email from the ASF dual-hosted git repository.
willholley pushed a commit to branch samesite_cookie
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 50cd470296732e2b75919eaeb68d3398b48c3e42
Author: Will Holley <wi...@gmail.com>
AuthorDate: Mon Jan 13 19:57:19 2020 +0000
Add SameSite support to auth cookie
Adds a new configuration field, `couch_httpd_auth.same_site` which
sets the `SameSite` attribute of the CouchDB auth cookie. If no
value is set (the default), no `SameSite` attribute is added.
Refs #2221
---
.vscode/settings.json | 3 ++
rel/overlay/etc/default.ini | 18 +++++-----
src/couch/src/couch_httpd_auth.erl | 18 ++++++++--
src/couch/test/exunit/same_site_cookie_tests.exs | 44 ++++++++++++++++++++++++
4 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..aa0a1ad
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "python.pythonPath": ".venv/bin/python3"
+}
\ No newline at end of file
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index 5fc8e07..85e4002 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -168,8 +168,8 @@ enable_xframe_options = false
; CouchDB can optionally enforce a maximum uri length;
; max_uri_length = 8000
; changes_timeout = 60000
-; config_whitelist =
-; max_uri_length =
+; config_whitelist =
+; max_uri_length =
; rewrite_limit = 100
; x_forwarded_host = X-Forwarded-Host
; x_forwarded_proto = X-Forwarded-Proto
@@ -178,7 +178,7 @@ enable_xframe_options = false
max_http_request_size = 4294967296 ; 4GB
; [httpd_design_handlers]
-; _view =
+; _view =
; [ioq]
; concurrency = 10
@@ -192,7 +192,7 @@ port = 6984
; [chttpd_auth_cache]
; max_lifetime = 600000
-; max_objects =
+; max_objects =
; max_size = 104857600
; [mem3]
@@ -203,7 +203,7 @@ port = 6984
; [fabric]
; all_docs_concurrency = 10
-; changes_duration =
+; changes_duration =
; shard_timeout_factor = 2
; uuid_prefix_len = 7
; request_timeout = 60000
@@ -242,9 +242,11 @@ iterations = 10 ; iterations for password hashing
; proxy_use_secret = false
; comma-separated list of public fields, 404 if empty
; public_fields =
-; secret =
+; secret =
; users_db_public = false
; cookie_domain = example.com
+; Set the SameSite cookie property for the auth cookie. If empty, the SameSite property is not set.
+; same_site =
; CSP (Content Security Policy) Support for _utils
[csp]
@@ -320,7 +322,7 @@ os_process_limit = 100
couch_mrview = true
[feature_flags]
-; This enables any database to be created as a partitioned databases (except system db's).
+; This enables any database to be created as a partitioned databases (except system db's).
; Setting this to false will stop the creation of paritioned databases.
; paritioned||allowed* = true will scope the creation of partitioned databases
; to databases with 'allowed' prefix.
@@ -563,7 +565,7 @@ compaction = false
; The default number of results returned from a search on a partition
; of a database.
; limit_partitions = 2000
-
+
; The maximum number of results that can be returned from a global
; search query (or any search query on a database without user-defined
; partitions). Attempts to set ?limit=N higher than this value will
diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl
index 515ce61..9b7bda5 100644
--- a/src/couch/src/couch_httpd_auth.erl
+++ b/src/couch/src/couch_httpd_auth.erl
@@ -156,7 +156,7 @@ proxy_authentication_handler(Req) ->
%% @deprecated
proxy_authentification_handler(Req) ->
proxy_authentication_handler(Req).
-
+
proxy_auth_user(Req) ->
XHeaderUserName = config:get("couch_httpd_auth", "x_auth_username",
"X-Auth-CouchDB-UserName"),
@@ -273,7 +273,7 @@ cookie_auth_cookie(Req, User, Secret, TimeStamp) ->
Hash = crypto:hmac(sha, Secret, SessionData),
mochiweb_cookies:cookie("AuthSession",
couch_util:encodeBase64Url(SessionData ++ ":" ++ ?b2l(Hash)),
- [{path, "/"}] ++ cookie_scheme(Req) ++ max_age() ++ cookie_domain()).
+ [{path, "/"}] ++ cookie_scheme(Req) ++ max_age() ++ cookie_domain() ++ same_site()).
ensure_cookie_auth_secret() ->
case config:get("couch_httpd_auth", "secret", undefined) of
@@ -457,6 +457,20 @@ cookie_domain() ->
_ -> [{domain, Domain}]
end.
+
+same_site() ->
+ SameSite = config:get("couch_httpd_auth", "same_site", ""),
+ case string:to_lower(SameSite) of
+ "" -> [];
+ "none" -> [{same_site, none}];
+ "lax" -> [{same_site, lax}];
+ "strict" -> [{same_site, strict}];
+ _ ->
+ couch_log:error("invalid config value couch_httpd_auth.same_site: ~p ",[SameSite]),
+ []
+ end.
+
+
reject_if_totp(User) ->
case get_totp_config(User) of
undefined ->
diff --git a/src/couch/test/exunit/same_site_cookie_tests.exs b/src/couch/test/exunit/same_site_cookie_tests.exs
new file mode 100644
index 0000000..bad32ad
--- /dev/null
+++ b/src/couch/test/exunit/same_site_cookie_tests.exs
@@ -0,0 +1,44 @@
+defmodule SameSiteCookieTests do
+ use CouchTestCase
+
+ @moduletag :authentication
+
+ def get_cookie(user, pass) do
+ resp = Couch.post("/_session", body: %{:username => user, :password => pass})
+
+ true = resp.body["ok"]
+ resp.headers[:"set-cookie"]
+ end
+
+ @tag config: [{"admins", "jan", "apple"}, {"couch_httpd_auth", "same_site", "None"}]
+ test "Set same_site None" do
+ cookie = get_cookie("jan", "apple")
+ assert cookie =~ "; SameSite=None"
+ end
+
+ @tag config: [{"admins", "jan", "apple"}, {"couch_httpd_auth", "same_site", ""}]
+ test "same_site not set" do
+ cookie = get_cookie("jan", "apple")
+ assert cookie
+ refute cookie =~ "; SameSite="
+ end
+
+ @tag config: [{"admins", "jan", "apple"}, {"couch_httpd_auth", "same_site", "Strict"}]
+ test "Set same_site Strict" do
+ cookie = get_cookie("jan", "apple")
+ assert cookie =~ "; SameSite=Strict"
+ end
+
+ @tag config: [{"admins", "jan", "apple"}, {"couch_httpd_auth", "same_site", "Lax"}]
+ test "Set same_site Lax" do
+ cookie = get_cookie("jan", "apple")
+ assert cookie =~ "; SameSite=Lax"
+ end
+
+ @tag config: [{"admins", "jan", "apple"}, {"couch_httpd_auth", "same_site", "Invalid"}]
+ test "Set same_site invalid" do
+ cookie = get_cookie("jan", "apple")
+ assert cookie
+ refute cookie =~ "; SameSite="
+ end
+end