Skip to content

Commit

Permalink
Adds support for "SameSite" cookie property (#1246)
Browse files Browse the repository at this point in the history
* Support SameSite cookie property (fixes issue #414)

* Support SameSite cookie property (fixes issue #414)

* Open in new tab

* Default fallback to None just in case someone forgets to clear cache

* * Force secure if SameSite None
* SameSite consistency for renew and delete functions

* Code formatting #OCD :)

* PHP 7.0 compatibility

* Fix pipeline errors

* Removed incorrect copyright docs
  • Loading branch information
kdckrs committed Dec 29, 2020
1 parent 0aec67d commit 26b9eee
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 20 deletions.
@@ -0,0 +1,16 @@
<?php

class Mage_Adminhtml_Model_System_Config_Source_Cookie_SameSite
{
/**
* @return array[]
*/
public function toOptionArray(): array
{
return [
['value' => 'None', 'label' => Mage::helper('adminhtml')->__('None')],
['value' => 'Strict', 'label' => Mage::helper('adminhtml')->__('Strict')],
['value' => 'Lax', 'label' => Mage::helper('adminhtml')->__('Lax')]
];
}
}
70 changes: 50 additions & 20 deletions app/code/core/Mage/Core/Model/Cookie.php
Expand Up @@ -37,6 +37,7 @@ class Mage_Core_Model_Cookie
const XML_PATH_COOKIE_PATH = 'web/cookie/cookie_path';
const XML_PATH_COOKIE_LIFETIME = 'web/cookie/cookie_lifetime';
const XML_PATH_COOKIE_HTTPONLY = 'web/cookie/cookie_httponly';
const XML_PATH_COOKIE_SAMESITE = 'web/cookie/cookie_samesite';

protected $_lifetime;

Expand Down Expand Up @@ -174,6 +175,20 @@ public function getHttponly()
return (bool)$httponly;
}

/**
* Retrieve use SameSite
*
* @return string
*/
public function getSameSite(): string
{
$sameSite = Mage::getStoreConfig(self::XML_PATH_COOKIE_SAMESITE, $this->getStore());
if (is_null($sameSite)) {
return 'None';
}
return (string)$sameSite;
}

/**
* Is https secure request
* Use secure on adminhtml only
Expand Down Expand Up @@ -202,9 +217,10 @@ public function isSecure()
* @param string $domain
* @param int|bool $secure
* @param bool $httponly
* @param string $sameSite
* @return $this
*/
public function set($name, $value, $period = null, $path = null, $domain = null, $secure = null, $httponly = null)
public function set($name, $value, $period = null, $path = null, $domain = null, $secure = null, $httponly = null, $sameSite = null)
{
/**
* Check headers sent
Expand Down Expand Up @@ -236,8 +252,34 @@ public function set($name, $value, $period = null, $path = null, $domain = null,
if (is_null($httponly)) {
$httponly = $this->getHttponly();
}
if (is_null($sameSite)) {
$sameSite = $this->getSameSite();
}

setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
if ($sameSite === 'None') {
// Enforce specification SameSite None requires secure
$secure = true;
}

if (PHP_VERSION_ID >= 70300) {
setcookie(
$name,
$value,
[
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'secure' => $secure,
'httponly' => $httponly,
'samesite' => $sameSite
]
);
} else {
if (!empty($sameSite)) {
$path.= "; samesite=${sameSite}";
}
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}

return $this;
}
Expand All @@ -251,16 +293,17 @@ public function set($name, $value, $period = null, $path = null, $domain = null,
* @param string $domain
* @param int|bool $secure
* @param bool $httponly
* @param string $sameSite
* @return $this
*/
public function renew($name, $period = null, $path = null, $domain = null, $secure = null, $httponly = null)
public function renew($name, $period = null, $path = null, $domain = null, $secure = null, $httponly = null, $sameSite = null)
{
if (($period === null) && !$this->getLifetime()) {
return $this;
}
$value = $this->_getRequest()->getCookie($name, false);
if ($value !== false) {
$this->set($name, $value, $period, $path, $domain, $secure, $httponly);
$this->set($name, $value, $period, $path, $domain, $secure, $httponly, $sameSite);
}
return $this;
}
Expand All @@ -284,9 +327,10 @@ public function get($name = null)
* @param string $domain
* @param int|bool $secure
* @param int|bool $httponly
* @param string $sameSite
* @return $this
*/
public function delete($name, $path = null, $domain = null, $secure = null, $httponly = null)
public function delete($name, $path = null, $domain = null, $secure = null, $httponly = null, $sameSite = null)
{
/**
* Check headers sent
Expand All @@ -295,20 +339,6 @@ public function delete($name, $path = null, $domain = null, $secure = null, $htt
return $this;
}

if (is_null($path)) {
$path = $this->getPath();
}
if (is_null($domain)) {
$domain = $this->getDomain();
}
if (is_null($secure)) {
$secure = $this->isSecure();
}
if (is_null($httponly)) {
$httponly = $this->getHttponly();
}

setcookie($name, null, null, $path, $domain, $secure, $httponly);
return $this;
return $this->set($name, null, null, $path, $domain, $secure, $httponly, $sameSite);
}
}
1 change: 1 addition & 0 deletions app/code/core/Mage/Core/etc/config.xml
Expand Up @@ -407,6 +407,7 @@
<cookie>
<cookie_lifetime>3600</cookie_lifetime>
<cookie_httponly>1</cookie_httponly>
<cookie_samesite>None</cookie_samesite>
<cookie_restriction>0</cookie_restriction>
<cookie_restriction_lifetime>31536000</cookie_restriction_lifetime>
</cookie>
Expand Down
10 changes: 10 additions & 0 deletions app/code/core/Mage/Core/etc/system.xml
Expand Up @@ -1574,6 +1574,16 @@
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</cookie_httponly>
<cookie_samesite translate="label">
<label>Same-Site</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_cookie_samesite</source_model>
<comment><![CDATA[<a target="_blank" href="https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00"/>https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00</a>]]></comment>
<sort_order>45</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</cookie_samesite>
<cookie_restriction translate="label">
<label>Cookie Restriction Mode</label>
<frontend_type>select</frontend_type>
Expand Down
4 changes: 4 additions & 0 deletions app/locale/en_US/Mage_Core.csv
Expand Up @@ -397,6 +397,10 @@
"Use Custom Admin Path","Use Custom Admin Path"
"Use Custom Admin URL","Use Custom Admin URL"
"Use HTTP Only","Use HTTP Only"
"Same-Site","Same-Site"
"None","None"
"Strict","Strict"
"Lax","Lax"
"Use SID on Frontend","Use SID on Frontend"
"Use Secure URLs in Admin","Use Secure URLs in Admin"
"Use Secure URLs in Frontend","Use Secure URLs in Frontend"
Expand Down

0 comments on commit 26b9eee

Please sign in to comment.