Project

General

Profile

Feature #7814 » 0001-Add-SameSite-support-to-setCookie_rev2.patch

Bruce Toll, 11/03/2020 02:26 PM

View differences:

src/Wt/WApplication.C
const std::string& value, int maxAge,
const std::string& domain,
const std::string& path,
bool secure)
bool secure,
CookieSameSite sameSite)
{
WDateTime expires = WDateTime::currentDateTime();
expires = expires.addSecs(maxAge);
session_->renderer().setCookie(name, value, expires, domain, path, secure);
session_->renderer().setCookie(name, value, expires, domain, path, secure, sameSite);
}
#ifndef WT_TARGET_JAVA
......
const WDateTime& expires,
const std::string& domain,
const std::string& path,
bool secure)
bool secure,
CookieSameSite sameSite)
{
session_->renderer().setCookie(name, value, expires, domain, path, secure);
session_->renderer().setCookie(name, value, expires, domain, path, secure, sameSite);
}
#endif // WT_TARGET_JAVA
......
{
session_->renderer().setCookie(name, std::string(),
WDateTime(WDate(1970,1,1)),
domain, path, false);
domain, path, false, CookieSameSite::Lax);
}
void WApplication::addMetaLink(const std::string &href,
src/Wt/WApplication.h
*/
void setCookie(const std::string& name, const std::string& value,
int maxAge, const std::string& domain = "",
const std::string& path = "", bool secure = false);
const std::string& path = "", bool secure = false,
CookieSameSite sameSite = CookieSameSite::Lax);
#ifndef WT_TARGET_JAVA
void setCookie(const std::string& name, const std::string& value,
const WDateTime& expires, const std::string& domain = "",
const std::string& path = "", bool secure = false);
const std::string& path = "", bool secure = false,
CookieSameSite sameSite = CookieSameSite::Lax);
#endif // WT_TARGET_JAVA
/*! \brief Removes a cookie.
src/Wt/WGlobal.h
};
#endif // WT_TARGET_JAVA
/*! \brief Enumeration that specifies the SameSite values for HTTP Cookies
*
* \sa WApplication::setCookie()
*/
enum class CookieSameSite {
None, //!< Sent in all contexts (note: generally not allowed if secure not specified)
Lax, //!< Sent for first-party and top-level GET from third-party
Strict //!< Sent for first-party only
};
}
#endif // WGLOBALS_H_
src/web/WebRenderer.C
LOGGER("WebRenderer");
WebRenderer::CookieValue::CookieValue()
: secure(false)
: secure(false),
sameSite(CookieSameSite::Lax)
{ }
WebRenderer::CookieValue::CookieValue(const std::string& v,
const std::string& p,
const std::string& d,
const WDateTime& e,
bool s)
bool s,
CookieSameSite sameSite)
: value(v),
path(p),
domain(d),
expires(e),
secure(s)
secure(s),
sameSite(sameSite)
{ }
WebRenderer::WebRenderer(WebSession& session)
......
void WebRenderer::setCookie(const std::string name, const std::string value,
const WDateTime& expires,
const std::string domain, const std::string path,
bool secure)
bool secure, CookieSameSite sameSite)
{
cookiesToSet_[name] = CookieValue(value, path, domain, expires, secure);
if (sameSite == CookieSameSite::None and !secure) {
LOG_WARN("setCookie: called with CookieSameSite::None, but not secure (cookie name: " << name << ")");
}
cookiesToSet_[name] = CookieValue(value, path, domain, expires, secure, sameSite);
}
void WebRenderer::setCaching(WebResponse& response, bool allowCache)
......
if (cookie.secure)
header << " secure;";
switch (cookie.sameSite) {
case CookieSameSite::None:
header << " SameSite=None;";
break;
case CookieSameSite::Lax:
header << " SameSite=Lax;";
break;
case CookieSameSite::Strict:
header << " SameSite=Strict;";
break;
}
response.addHeader("Set-Cookie", header.str());
}
cookiesToSet_.clear();
......
session_.multiSessionId(),
WDateTime::currentDateTime().addSecs(conf.multiSessionCookieTimeout()),
"", "",
session_.env().urlScheme() == "https");
session_.env().urlScheme() == "https",
CookieSameSite::Lax);
}
void WebRenderer::renderMultiSessionCookieUpdate(WStringStream &out)
src/web/WebRenderer.h
void setCookie(const std::string name, const std::string value,
const WDateTime& expires, const std::string domain,
const std::string path, bool secure);
const std::string path, bool secure,
CookieSameSite sameSite);
bool preLearning() const { return learning_; }
void learningIncomplete();
......
std::string domain;
WDateTime expires;
bool secure;
CookieSameSite sameSite;
CookieValue();
CookieValue(const std::string& v, const std::string& p,
const std::string& d, const WDateTime& e, bool secure);
const std::string& d, const WDateTime& e, bool secure,
CookieSameSite sameSite);
};
WebSession& session_;
src/web/WebSession.C
sessionIdCookie_ = WRandom::generateId();
sessionIdCookieChanged_ = true;
renderer().setCookie("Wt" + sessionIdCookie_, "1", Wt::WDateTime(), "", "",
env_->urlScheme() == "https");
env_->urlScheme() == "https", CookieSameSite::Strict);
}
}
......
if (!useUrlRewriting()) {
std::string cookieName = env_->deploymentPath();
renderer().setCookie(cookieName, sessionId_, WDateTime(), "", "", env_->urlScheme() == "https");
renderer().setCookie(cookieName, sessionId_, WDateTime(), "", "",
env_->urlScheme() == "https", CookieSameSite::Strict);
}
if (controller_->configuration().sessionIdCookie()) {
sessionIdCookie_ = WRandom::generateId();
sessionIdCookieChanged_ = true;
renderer().setCookie("Wt" + sessionIdCookie_, "1", WDateTime(), "", "",
env_->urlScheme() == "https");
env_->urlScheme() == "https", CookieSameSite::Strict);
}
}
#endif // WT_TARGET_JAVA
src/web/skeleton/Boot.js
_$_$if_COOKIE_CHECKS_$_();
// client-side cookie support
var testcookie='jscookietest=valid';
var testcookie='jscookietest=valid;SameSite=Lax';
doc.cookie=testcookie;
no_replace = no_replace ||
(_$_USE_COOKIES_$_ && doc.cookie.indexOf(testcookie) != -1);
doc.cookie=testcookie+';expires=Thu, 01 Jan 1970 00:00:00 GMT';
doc.cookie=testcookie+';expires=Thu, 01 Jan 1970 00:00:00 GMT;SameSite=Lax';
// server-side cookie support
doc.cookie='WtTestCookie=ok;path=/;expires=' + inOneSecond.toGMTString();
doc.cookie='WtTestCookie=ok;path=/;expires=' + inOneSecond.toGMTString() + ';SameSite=Lax';
_$_$endif_$_();
// hash to query
......
if (!htmlHistory && canonicalUrl.length > 1) {
_$_$if_HYBRID_$_();
var pathcookie='WtInternalPath=' + escape(_$_INTERNAL_PATH_$_)
+ ';path=/;expires=' + inOneSecond.toGMTString();
+ ';path=/;expires=' + inOneSecond.toGMTString() + ';SameSite=Lax';
doc.cookie=pathcookie;
_$_$endif_$_();
/* Otherwise we do not get a page reload */
(2-2/2)