205 lines
7.7 KiB
Diff
205 lines
7.7 KiB
Diff
|
From b68ac577b465f54e7eb38e48a65e5cf4c88c74c5 Mon Sep 17 00:00:00 2001
|
||
|
From: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
|
||
|
Date: Thu, 3 Sep 2020 16:52:30 +0200
|
||
|
Subject: [PATCH 19/19] add SameSite attribute on cookie clearance / logout
|
||
|
|
||
|
bump to 2.4.4.1; thanks @v0gler
|
||
|
|
||
|
Signed-off-by: Hans Zandbelt <hans.zandbelt@zmartzone.eu>
|
||
|
(cherry picked from commit 314000d179c2d08af6897725f37980e1f0891aa6)
|
||
|
---
|
||
|
ChangeLog | 4 ++++
|
||
|
src/mod_auth_openidc.c | 42 +++++++++++++++++++++++-------------------
|
||
|
src/mod_auth_openidc.h | 5 +++++
|
||
|
src/session.c | 16 +++++++++-------
|
||
|
4 files changed, 41 insertions(+), 26 deletions(-)
|
||
|
|
||
|
diff --git a/ChangeLog b/ChangeLog
|
||
|
index 3db7110..eba2ebc 100644
|
||
|
--- a/ChangeLog
|
||
|
+++ b/ChangeLog
|
||
|
@@ -1,3 +1,7 @@
|
||
|
+09/03/2020
|
||
|
+- add SameSite attribute on cookie clearance / logout; thanks @v0gler
|
||
|
+- bump to 2.4.4.1
|
||
|
+
|
||
|
02/03/2020
|
||
|
- fix: also add SameSite=None to by-value session cookies
|
||
|
- bump to 2.4.2rc0
|
||
|
diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c
|
||
|
index 0d2b37c..68fa2ce 100644
|
||
|
--- a/src/mod_auth_openidc.c
|
||
|
+++ b/src/mod_auth_openidc.c
|
||
|
@@ -717,7 +717,8 @@ static int oidc_delete_oldest_state_cookies(request_rec *r,
|
||
|
oidc_warn(r,
|
||
|
"deleting oldest state cookie: %s (time until expiry " APR_TIME_T_FMT " seconds)",
|
||
|
oldest->name, apr_time_sec(oldest->timestamp - apr_time_now()));
|
||
|
- oidc_util_set_cookie(r, oldest->name, "", 0, NULL);
|
||
|
+ oidc_util_set_cookie(r, oldest->name, "", 0,
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
if (prev_oldest)
|
||
|
prev_oldest->next = oldest->next;
|
||
|
else
|
||
|
@@ -762,7 +763,7 @@ static int oidc_clean_expired_state_cookies(request_rec *r, oidc_cfg *c,
|
||
|
oidc_error(r, "state (%s) has expired",
|
||
|
cookieName);
|
||
|
oidc_util_set_cookie(r, cookieName, "", 0,
|
||
|
- NULL);
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
} else {
|
||
|
if (first == NULL) {
|
||
|
first = apr_pcalloc(r->pool,
|
||
|
@@ -779,6 +780,12 @@ static int oidc_clean_expired_state_cookies(request_rec *r, oidc_cfg *c,
|
||
|
number_of_valid_state_cookies++;
|
||
|
}
|
||
|
oidc_proto_state_destroy(proto_state);
|
||
|
+ } else {
|
||
|
+ oidc_warn(r,
|
||
|
+ "state cookie could not be retrieved/decoded, deleting: %s",
|
||
|
+ cookieName);
|
||
|
+ oidc_util_set_cookie(r, cookieName, "", 0,
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -816,7 +823,7 @@ static apr_byte_t oidc_restore_proto_state(request_rec *r, oidc_cfg *c,
|
||
|
}
|
||
|
|
||
|
/* clear state cookie because we don't need it anymore */
|
||
|
- oidc_util_set_cookie(r, cookieName, "", 0, NULL);
|
||
|
+ oidc_util_set_cookie(r, cookieName, "", 0, OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
|
||
|
*proto_state = oidc_proto_state_from_cookie(r, c, cookieValue);
|
||
|
if (*proto_state == NULL)
|
||
|
@@ -916,9 +923,7 @@ static int oidc_authorization_request_set_cookie(request_rec *r, oidc_cfg *c,
|
||
|
|
||
|
/* set it as a cookie */
|
||
|
oidc_util_set_cookie(r, cookieName, cookieValue, -1,
|
||
|
- c->cookie_same_site ?
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_LAX :
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
+ OIDC_COOKIE_SAMESITE_LAX(c));
|
||
|
|
||
|
return HTTP_OK;
|
||
|
}
|
||
|
@@ -2183,9 +2188,7 @@ static int oidc_discovery(request_rec *r, oidc_cfg *cfg) {
|
||
|
|
||
|
/* set CSRF cookie */
|
||
|
oidc_util_set_cookie(r, OIDC_CSRF_NAME, csrf, -1,
|
||
|
- cfg->cookie_same_site ?
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_STRICT :
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
+ OIDC_COOKIE_SAMESITE_STRICT(cfg));
|
||
|
|
||
|
/* see if we need to preserve POST parameters through Javascript/HTML5 storage */
|
||
|
if (oidc_post_preserve_javascript(r, url, NULL, NULL) == TRUE)
|
||
|
@@ -2278,9 +2281,7 @@ static int oidc_discovery(request_rec *r, oidc_cfg *cfg) {
|
||
|
s = apr_psprintf(r->pool, "%s</form>\n", s);
|
||
|
|
||
|
oidc_util_set_cookie(r, OIDC_CSRF_NAME, csrf, -1,
|
||
|
- cfg->cookie_same_site ?
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_STRICT :
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
+ OIDC_COOKIE_SAMESITE_STRICT(cfg));
|
||
|
|
||
|
char *javascript = NULL, *javascript_method = NULL;
|
||
|
char *html_head =
|
||
|
@@ -2501,7 +2502,8 @@ static int oidc_handle_discovery_response(request_rec *r, oidc_cfg *c) {
|
||
|
if (csrf_cookie) {
|
||
|
|
||
|
/* clean CSRF cookie */
|
||
|
- oidc_util_set_cookie(r, OIDC_CSRF_NAME, "", 0, NULL);
|
||
|
+ oidc_util_set_cookie(r, OIDC_CSRF_NAME, "", 0,
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
|
||
|
/* compare CSRF cookie value with query parameter value */
|
||
|
if ((csrf_query == NULL)
|
||
|
@@ -2639,12 +2641,12 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
|
||
|
|
||
|
oidc_debug(r, "enter (url=%s)", url);
|
||
|
|
||
|
- /* if there's no remote_user then there's no (stored) session to kill */
|
||
|
- if (session->remote_user != NULL) {
|
||
|
-
|
||
|
- /* remove session state (cq. cache entry and cookie) */
|
||
|
- oidc_session_kill(r, session);
|
||
|
- }
|
||
|
+ /*
|
||
|
+ * remove session state (cq. cache entry and cookie)
|
||
|
+ * always clear the session cookie because the cookie may be not sent (but still in the browser)
|
||
|
+ * due to SameSite policies
|
||
|
+ */
|
||
|
+ oidc_session_kill(r, session);
|
||
|
|
||
|
/* see if this is the OP calling us */
|
||
|
if (oidc_is_front_channel_logout(url)) {
|
||
|
@@ -2661,6 +2663,8 @@ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c,
|
||
|
const char *accept = oidc_util_hdr_in_accept_get(r);
|
||
|
if ((apr_strnatcmp(url, OIDC_IMG_STYLE_LOGOUT_PARAM_VALUE) == 0)
|
||
|
|| ((accept) && strstr(accept, OIDC_CONTENT_TYPE_IMAGE_PNG))) {
|
||
|
+ // terminate with DONE instead of OK
|
||
|
+ // to avoid Apache returning auth/authz error 401 for the redirect URI
|
||
|
return oidc_util_http_send(r,
|
||
|
(const char *) &oidc_transparent_pixel,
|
||
|
sizeof(oidc_transparent_pixel), OIDC_CONTENT_TYPE_IMAGE_PNG,
|
||
|
diff --git a/src/mod_auth_openidc.h b/src/mod_auth_openidc.h
|
||
|
index 5f1a79a..6821d0c 100644
|
||
|
--- a/src/mod_auth_openidc.h
|
||
|
+++ b/src/mod_auth_openidc.h
|
||
|
@@ -215,6 +215,11 @@ APLOG_USE_MODULE(auth_openidc);
|
||
|
#define OIDC_COOKIE_EXT_SAME_SITE_STRICT "SameSite=Strict"
|
||
|
#define OIDC_COOKIE_EXT_SAME_SITE_NONE "SameSite=None"
|
||
|
|
||
|
+#define OIDC_COOKIE_SAMESITE_STRICT(c) \
|
||
|
+ c->cookie_same_site ? OIDC_COOKIE_EXT_SAME_SITE_STRICT : OIDC_COOKIE_EXT_SAME_SITE_NONE
|
||
|
+#define OIDC_COOKIE_SAMESITE_LAX(c) \
|
||
|
+ c->cookie_same_site ? OIDC_COOKIE_EXT_SAME_SITE_LAX : OIDC_COOKIE_EXT_SAME_SITE_NONE
|
||
|
+
|
||
|
/* https://tools.ietf.org/html/draft-ietf-tokbind-ttrp-01 */
|
||
|
#define OIDC_TB_CFG_PROVIDED_ENV_VAR "Sec-Provided-Token-Binding-ID"
|
||
|
|
||
|
diff --git a/src/session.c b/src/session.c
|
||
|
index e7194bd..539ea21 100644
|
||
|
--- a/src/session.c
|
||
|
+++ b/src/session.c
|
||
|
@@ -155,7 +155,7 @@ static apr_byte_t oidc_session_load_cache(request_rec *r, oidc_session_t *z) {
|
||
|
|
||
|
/* delete the session cookie */
|
||
|
oidc_util_set_cookie(r, oidc_cfg_dir_cookie(r), "", 0,
|
||
|
- NULL);
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
/* delete the cache entry */
|
||
|
rc = oidc_cache_set_session(r, z->uuid, NULL, 0);
|
||
|
/* clear the session */
|
||
|
@@ -208,7 +208,8 @@ static apr_byte_t oidc_session_save_cache(request_rec *r, oidc_session_t *z,
|
||
|
|
||
|
} else {
|
||
|
/* clear the cookie */
|
||
|
- oidc_util_set_cookie(r, oidc_cfg_dir_cookie(r), "", 0, NULL);
|
||
|
+ oidc_util_set_cookie(r, oidc_cfg_dir_cookie(r), "", 0,
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
|
||
|
/* remove the session from the cache */
|
||
|
rc = oidc_cache_set_session(r, z->uuid, NULL, 0);
|
||
|
@@ -245,11 +246,12 @@ static apr_byte_t oidc_session_save_cookie(request_rec *r, oidc_session_t *z,
|
||
|
oidc_util_set_chunked_cookie(r, oidc_cfg_dir_cookie(r), cookieValue,
|
||
|
c->persistent_session_cookie ? z->expiry : -1,
|
||
|
c->session_cookie_chunk_size,
|
||
|
- c->cookie_same_site ?
|
||
|
- (first_time ?
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_LAX :
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_STRICT) :
|
||
|
- OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
+ (z->state == NULL) ? OIDC_COOKIE_EXT_SAME_SITE_NONE :
|
||
|
+ c->cookie_same_site ?
|
||
|
+ (first_time ?
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_LAX :
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_STRICT) :
|
||
|
+ OIDC_COOKIE_EXT_SAME_SITE_NONE);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
--
|
||
|
2.26.2
|
||
|
|