Skip to content
Snippets Groups Projects
Unverified Commit d65f8671 authored by Patrick's avatar Patrick Committed by GitHub
Browse files

Allow easy enabling of SameSite = 'None' (#1382)

parent 0c07d7bd
No related branches found
No related tags found
No related merge requests found
...@@ -564,7 +564,7 @@ $config = [ ...@@ -564,7 +564,7 @@ $config = [
* Example: * Example:
* 'session.cookie.samesite' => 'None', * 'session.cookie.samesite' => 'None',
*/ */
'session.cookie.samesite' => null, 'session.cookie.samesite' => \SimpleSAML\Utils\HTTP::canSetSameSiteNone() ? 'None' : null,
/* /*
* Options to override the default settings for php sessions. * Options to override the default settings for php sessions.
...@@ -792,7 +792,7 @@ $config = [ ...@@ -792,7 +792,7 @@ $config = [
'language.cookie.secure' => false, 'language.cookie.secure' => false,
'language.cookie.httponly' => false, 'language.cookie.httponly' => false,
'language.cookie.lifetime' => (60 * 60 * 24 * 900), 'language.cookie.lifetime' => (60 * 60 * 24 * 900),
'language.cookie.samesite' => null, 'language.cookie.samesite' => \SimpleSAML\Utils\HTTP::canSetSameSiteNone() ? 'None' : null,
/** /**
* Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage().
......
...@@ -18,6 +18,51 @@ use SimpleSAML\XHTML\Template; ...@@ -18,6 +18,51 @@ use SimpleSAML\XHTML\Template;
*/ */
class HTTP class HTTP
{ {
/**
* Determine if the user agent can support cookies being sent with SameSite equal to "None".
* Browsers with out support may drop the cookie and or treat is a stricter setting
* Browsers with support may have additional requirements on setting it on non-secure websites.
*
* Based on the Azure teams experience rolling out support and Chromium's advice
* https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
* https://www.chromium.org/updates/same-site/incompatible-clients
* @return bool true if user agent supports a None value for SameSite.
*/
public static function canSetSameSiteNone(): bool
{
$useragent = $_SERVER['HTTP_USER_AGENT'] ?? null;
if (!$useragent) {
return true;
}
// All iOS 12 based browsers have no support
if (strpos($useragent, "CPU iPhone OS 12") !== false || strpos($useragent, "iPad; CPU OS 12") !== false) {
return false;
}
// Safari Mac OS X 10.14 has no support
// - Safari on Mac OS X.
if (strpos($useragent, "Macintosh; Intel Mac OS X 10_14") !== false) {
// regular safari
if (strpos($useragent, "Version/") !== false && strpos($useragent, "Safari") !== false) {
return false;
} elseif (preg_match('|AppleWebKit/[\.\d]+ \(KHTML, like Gecko\)$|', $useragent)) {
return false;
}
}
// Chrome based UCBrowser may have support (>= 12.13.2) even though its chrome version is old
$matches = [];
if (preg_match('|UCBrowser/(\d+\.\d+\.\d+)[\.\d]*|', $useragent, $matches)) {
return version_compare($matches[1], '12.13.2', '>=');
}
// Chrome 50-69 may have broken SameSite=None and don't require it to be set
if (strpos($useragent, "Chrome/5") !== false || strpos($useragent, "Chrome/6") !== false) {
return false;
}
return true;
}
/** /**
* Obtain a URL where we can redirect to securely post a form with the given data to a specific destination. * Obtain a URL where we can redirect to securely post a form with the given data to a specific destination.
* *
......
...@@ -526,4 +526,57 @@ class HTTPTest extends ClearStateTestCase ...@@ -526,4 +526,57 @@ class HTTPTest extends ClearStateTestCase
$this->assertMatchesRegularExpression('/\b[Ss]ame[Ss]ite=Lax(;|$)/', $headers[2]); $this->assertMatchesRegularExpression('/\b[Ss]ame[Ss]ite=Lax(;|$)/', $headers[2]);
$this->assertMatchesRegularExpression('/\b[Ss]ame[Ss]ite=Strict(;|$)/', $headers[3]); $this->assertMatchesRegularExpression('/\b[Ss]ame[Ss]ite=Strict(;|$)/', $headers[3]);
} }
/**
* Test detecting if user agent supports None
* @dataProvider detectSameSiteProvider
* @param null|string $userAgent The user agent. Null means not set, like with CLI
* @param bool $supportsNone None can be set as a SameSite flag
*/
public function testDetectSameSiteNoneBehavior(?string $userAgent, bool $supportsNone): void
{
if ($userAgent) {
$_SERVER['HTTP_USER_AGENT'] = $userAgent;
}
$this->assertEquals($supportsNone, HTTP::canSetSameSiteNone(), $userAgent ?? 'No user agent set');
}
public function detectSameSiteProvider(): array
{
// @codingStandardsIgnoreStart
return [
[null, true],
['some-new-browser', true],
//Browsers that can handle 'None'
// Chrome
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36', true],
// Chome on windows
['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', true],
// Chrome linux
['Mozilla/5.0 (X11; HasCodingOs 1.0; Linux x64) AppleWebKit/637.36 (KHTML, like Gecko) Chrome/70.0.3112.101 Safari/637.36 HasBrowser/5.0', true],
// Safari iOS 13
['Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.2 Mobile/15E148 Safari/604.1', true],
// Mac OS X with support
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15', true],
// UC Browser with support
['Mozilla/5.0 (Linux; U; Android 9; en-US; SM-A705FN Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.2.1208 Mobile Safari/537.36', true],
['Mozilla/5.0 (Linux; U; Android 10; en-US; RMX2020 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.5.1209 Mobile Safari/537.36', true],
// Embedded Mac with support
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko)', true],
// Browser without support
// Old Safari on mac
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15', false],
// Old Safari on iOS 12 (phone and ipad
['Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Mobile/15E148 Safari/604.1', false],
['Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/16A5288q Safari/605.1.15', false],
// Chromium without support
['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36', false],
// UC Browser without support
['Mozilla/5.0 (Linux; U; Android 8.1.0; zh-CN; EML-AL00 Build/HUAWEIEML-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 baidu.sogo.uc.UCBrowser/11.9.4.974 UWS/2.13.1.48 Mobile Safari/537.36 AliApp(DingTalk/4.5.11) com.alibaba.android.rimet/10487439 Channel/227200 language/zh-CN', false],
['Mozilla/5.0 (Linux; U; Android 7.1.1; en-US; CPH1723 Build/N6F26Q) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.0.1207 Mobile Safari/537.36', false],
// old embedded browser
['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko)', false]
];
// @codingStandardsIgnoreEnd
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment