[cpp-xmltooling] branch master updated: SSPCPP-878 - SameSite workaround using second cookie

Scott Cantor cantor.2 at osu.edu
Tue Feb 4 12:15:28 EST 2020


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch master
in repository cpp-xmltooling.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-xmltooling.git;a=commit;h=5e3cc9d4cabb8ce38cbfff84bfeb69ffea438601

The following commit(s) were added to refs/heads/master by this push:
       new  5e3cc9d   SSPCPP-878 - SameSite workaround using second cookie
5e3cc9d is described below

commit 5e3cc9d4cabb8ce38cbfff84bfeb69ffea438601
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Feb 4 12:14:24 2020 -0500

    SSPCPP-878 - SameSite workaround using second cookie
    
    https://issues.shibboleth.net/jira/browse/SSPCPP-878
---
 xmltooling/io/HTTPRequest.cpp  | 14 ++++++++++++--
 xmltooling/io/HTTPRequest.h    |  7 ++++++-
 xmltooling/io/HTTPResponse.cpp | 33 +++++++++++++++++++++++++++++----
 xmltooling/io/HTTPResponse.h   | 17 ++++++++++++++++-
 4 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/xmltooling/io/HTTPRequest.cpp b/xmltooling/io/HTTPRequest.cpp
index e4f5038..3d47b47 100644
--- a/xmltooling/io/HTTPRequest.cpp
+++ b/xmltooling/io/HTTPRequest.cpp
@@ -239,8 +239,18 @@ const map<string,string>& HTTPRequest::getCookies() const
     return m_cookieMap;
 }
 
-const char* HTTPRequest::getCookie(const char* name) const
+const char* HTTPRequest::getCookie(const char* name, bool sameSiteFallback) const
 {
     map<string,string>::const_iterator lookup = getCookies().find(name);
-    return (lookup==m_cookieMap.end()) ? nullptr : lookup->second.c_str();
+    if (lookup != m_cookieMap.end()) {
+        return lookup->second.c_str();
+    } else if (sameSiteFallback) {
+        string hackeryName(name);
+        lookup = getCookies().find(hackeryName.append("_fgwars"));
+        if (lookup != m_cookieMap.end()) {
+            return lookup->second.c_str();
+        }
+    }
+
+    return nullptr;
 }
diff --git a/xmltooling/io/HTTPRequest.h b/xmltooling/io/HTTPRequest.h
index 6568475..064850d 100644
--- a/xmltooling/io/HTTPRequest.h
+++ b/xmltooling/io/HTTPRequest.h
@@ -95,11 +95,16 @@ namespace xmltooling {
 
         /**
          * Get a cookie value supplied by the client.
+         *
+         * The boolean flag enables the workaround for older clients with
+         * broken SameSite support by looking for a second cookie with
+         * a decorated name that would not carry the SameSite flag.
          * 
          * @param name  name of cookie
+         * @param sameSiteFallback enables lookaside to fallback cookie name
          * @return  cookie value or nullptr
          */
-        virtual const char* getCookie(const char* name) const;
+        virtual const char* getCookie(const char* name, bool sameSiteFallback=false) const;
 
         /**
          * Gets all the cookies supplied by the client.
diff --git a/xmltooling/io/HTTPResponse.cpp b/xmltooling/io/HTTPResponse.cpp
index 6fbe601..9a16814 100644
--- a/xmltooling/io/HTTPResponse.cpp
+++ b/xmltooling/io/HTTPResponse.cpp
@@ -86,11 +86,36 @@ void HTTPResponse::setContentType(const char* type)
     setResponseHeader("Content-Type", type);
 }
 
-void HTTPResponse::setCookie(const char* name, const char* value)
+void HTTPResponse::setCookie(const char* name, const char* value, samesite_t sameSiteValue, bool sameSiteFallback)
 {
-    string cookie(name);
-    cookie = cookie + '=' + value;
-    setResponseHeader("Set-Cookie", cookie.c_str());
+    if (sameSiteValue != SAMESITE_ABSENT) {
+        // Add SameSite to the primary cookie and optionally set a fallback cookie without SameSite.
+        string ssCookie(name);
+        ssCookie.append("=").append(value).append("; SameSite=");
+        switch (sameSiteValue) {
+            case SAMESITE_NONE:
+                ssCookie.append("None");
+                break;
+            case SAMESITE_LAX:
+                ssCookie.append("Lax");
+                break;
+            case SAMESITE_STRICT:
+                ssCookie.append("Strict");
+                break;
+            default:
+                throw IOException("Invalid SameSite value supplied");
+        }
+        setResponseHeader("Set-Cookie", ssCookie.c_str());
+
+        if (sameSiteFallback) {
+            string hackedName(name);
+            setResponseHeader("Set-Cookie", hackedName.append("_fgwars=").append(value).c_str());
+        }
+    }
+    else {
+        string cookie(name);
+        setResponseHeader("Set-Cookie", cookie.append("=").append(value).c_str());
+    }
 }
 
 void HTTPResponse::setResponseHeader(const char* name, const char* value, bool replace)
diff --git a/xmltooling/io/HTTPResponse.h b/xmltooling/io/HTTPResponse.h
index 3d6ee70..513f98f 100644
--- a/xmltooling/io/HTTPResponse.h
+++ b/xmltooling/io/HTTPResponse.h
@@ -65,13 +65,28 @@ namespace xmltooling {
          */
         virtual void setResponseHeader(const char* name, const char* value, bool replace = false);
 
+        /** Cookie SameSite values. */
+        enum samesite_t {
+            SAMESITE_ABSENT = 0,
+            SAMESITE_NONE = 1,
+            SAMESITE_LAX = 2,
+            SAMESITE_STRICT = 3
+        };
+
         /**
          * Sets a client cookie.
          * 
+         * The boolean flag enables the workaround for older clients with
+         * broken SameSite support by setting a second cookie with
+         * a decorated name that would not carry the SameSite flag.
+         *
          * @param name  cookie name
          * @param value value to set, or nullptr to clear
+         * @param sameSiteValue the SameSite value to apply to the cookie
+         * @param sameSiteFallback enables setting of a fallback cookie
          */
-        virtual void setCookie(const char* name, const char* value);
+        virtual void setCookie(const char* name, const char* value,
+            samesite_t sameSiteValue = SAMESITE_ABSENT, bool sameSiteFallback = false);
         
         /**
          * Redirect the client to the specified URL and complete the response.

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list