PHP setcookie" SameSite =严格"?

时间:2016-09-28 14:48:16

标签: php security cookies

我最近阅读了#34; RFC 6265"在属性"同一网站",我看了一些在2016年4月讨论过的文章,"同一网站"属性已针对Chrome 51和Opera 39实现...

我想知道当前的PHP是否支持使用此属性创建cookie?

参考:

10 个答案:

答案 0 :(得分:19)

基于Steffen's answer above,这是我用来同时支持php <= 7.2和php> = 7.3的方法:

/**
 * Support samesite cookie flag in both php 7.2 (current production) and php >= 7.3 (when we get there)
 * From: https://github.com/GoogleChromeLabs/samesite-examples/blob/master/php.md and https://stackoverflow.com/a/46971326/2308553 
 *  * @param [type] $name
 * @param [type] $value
 * @param [type] $expire
 * @param [type] $path
 * @param [type] $domain
 * @param [type] $secure
 * @param [type] $httponly
 * @param [type] $samesite
 * @return void
 */
function setcookieSameSite($name, $value, $expire, $path, $domain, $secure, $httponly, $samesite="None")
{
    if (PHP_VERSION_ID < 70300) {
        setcookie($name, $value, $expire, "$path; samesite=$samesite", $domain, $secure, $httponly);
    }
    else {
        setcookie($name, $value, [
            'expires' => $expire,
            'path' => $path,
            'domain' => $domain,
            'samesite' => $samesite,
            'secure' => $secure,
            'httponly' => $httponly,
        ]);
    }
}

答案 1 :(得分:17)

[重要更新:正如@caw在下面指出的那样,这个黑客WILL BREAK in PHP 7.3。现在停止使用它来避免不愉快的惊喜!或者至少将它包装在像if (PHP_VERSION_ID < 70300) { ... } else { ... }这样的PHP版本中。]

好像你可以滥用&#34;路径&#34;或&#34;域名&#34; PHP&#34; setcookie&#34;的参数函数隐藏SameSite属性,因为PHP不会以分号转义:

setcookie('samesite-test', '1', 0, '/; samesite=strict');

然后PHP发送以下HTTP标头:

  

Set-Cookie:samesite-test = 1;路径= /; samesite =严格

我刚刚在几分钟前发现了这个,所以请自行测试!我使用PHP 7.1.11。

答案 2 :(得分:17)

1。对于PHP> = v7.3

您将在$samesite函数中使用setcookie参数

bool setcookie ( 
    string $name 
    string $value = ""
    int $expire = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false,
    string $samesite = "" // Lax or Strict
)

在此处查看更多-PHP RFC: Same Site Cookie

2。对于PHP

根据您的代码库/需求,您可以使用以下解决方案/解决方法之一

2.1使用Apache配置设置SameSite cookie

您可以将以下行添加到您的Apache配置中

Header always edit Set-Cookie (.*) "$1; SameSite=Lax"

这将使用SameSite=Lax标志更新您的所有cookie

在此处查看更多信息:https://blog.giantgeek.com/?p=1872

2.2使用Nginx配置设置SameSite Cookie

location / {
    # your usual config ...
    # hack, set all cookies to secure, httponly and samesite (strict or lax)
    proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
}

与此处相同,这也会使用SameSite=Lax标志更新您的所有cookie

在此处查看更多信息:https://serverfault.com/questions/849888/add-samesite-to-cookies-using-nginx-as-reverse-proxy

2.3使用header方法设置SameSite Cookie

我们知道cookie只是HTTP请求中具有以下结构的标头

Set-Cookie: key=value; path=/; domain=example.org; HttpOnly; SameSite=Lax

所以我们只需使用header方法设置cookie

header("Set-Cookie: key=value; path=/; domain=example.org; HttpOnly; SameSite=Lax");

实际上,Symphony并不在等待PHP 7.3,而是已经在see here

的幕后做了。

您也可以在Laravel中使用它,因为Laravel在后台使用了Symphony的Symfony\Component\HttpFoundation\Cookie

2.4使用setcookie方法中的错误设置SameSite Cookie

setcookie('cookie-name', '1', 0, '/; samesite=strict');

请谨慎操作,这是PHP setcookie方法中的已知错误,并且已在PHP7.3版本中解决,请参见此处-https://github.com/php/php-src/commit/5cb825df7251aeb28b297f071c35b227a3949f01

答案 3 :(得分:3)

我写了一个用于设置相同站点cookie的类。

https://github.com/ovunctukenmez/SameSiteCookieSetter

它适用于所有PHP版本。 它还会检查浏览器是否正确支持samesite参数。

这里是用法:

//set samesite strict php cookie
SameSiteCookieSetter::setcookie('samesite_test','testvalue', array('samesite' => 'Strict'));

答案 4 :(得分:2)

根据this site,似乎是PHP 7.3的问题。截至投票结果,正在实现对cookie相关函数的更一般扩展+在php.ini文件中可能还有一个新密钥。

但是正如Marc B已经写过的那样,你可以使用header()函数调用,我会在一些文件中用它来包含其他初始的东西。

答案 5 :(得分:1)

在Marty Aghajanyan的回答中添加(因为显然我可以回答,但尚未发表评论)

在Apache 2.4.29(Ubuntu)中,通过mod_headers与PHP一起在Apache中执行此操作对我不起作用。在查看文档(http://www.balkangreenfoundation.org/manual/en/mod/mod_headers.html)时,我注意到“始终”条件在某些情况下无法在相同的响应头池中起作用。因此,以下内容对我来说可以设置SameSite参数。 (就我而言,我最近的Chrome 80更新没有设置)

Header edit Set-Cookie ^(.*)$ "$1; Secure; SameSite=None"

文档还建议,如果您想覆盖所有基础,则可以在有和没有“总是”的情况下添加指令,但是我尚未对此进行测试。

答案 6 :(得分:0)

值得一提的是,macOS和iOS上的Safari 12均无法识别SameSite属性的None值,并且默认值为Strict。

版本13将接受“无”,但是如果未明确设置值,则默认为“松散”。

这是一个很好的解释:

https://www.thinktecture.com/en/identity/samesite/samesite-in-a-nutshell/

答案 7 :(得分:0)

有很多示例显示了如何设置此属性,但是没有很多解释。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_attribute

如果需要跨域发送cookie,请使用None指令选择退出SameSite限制。 None指令要求还使用Secure属性。

SameSite设置为NoneLax的示例仅适用于跨域方案。如果您的代码不是跨域代码,请使用Strict

答案 8 :(得分:0)

这也可能对仍在苦苦挣扎并使用 PHP >= 7.3.x 和 CI 3.1.11 的人有所帮助

在根目录下的index.php中,添加下面的一行

if(isset($_COOKIE["PHPSESSID"])){
    header('Set-Cookie: PHPSESSID='.$_COOKIE["PHPSESSID"].'; SameSite=None');
}

它对我有用,在尝试了所有之后(徒劳)

答案 9 :(得分:-1)

在实时网站上解决Samesite问题后,您可能在为本地开发环境设置PHPSESSID时遇到了问题。特别是如果您不使用HTTPS并通过在主机文件中映射IP在本地使用真实域名,则为该域名;

要在Chrome上解决此问题;首先,您必须打开chrome标志管理页面

chrome://flags/#same-site-by-default-cookies

并将这些标志设置为禁用

  • “默认情况下,SameSite Cookie”
  • “没有SameSite的Cookie必须是安全的”

然后重新启动chrome;

如果您曾经访问过HTTPS站点,那么仍无法设置PHPSESSID的cookie,并且您将没有php会话。该安全cookie将已经设置。因此,您需要先将其删除。因为如果您已经具有相同名称的安全cookie,则无法设置非安全cookie。

您应该打开实时网站(使用https)并打开开发人员工具/应用程序,然后删除使用https设置的cookie。并且无需再次重新加载实时站点,而是将主机文件设置回本地并打开非https本地驱动的网站。现在,您的PHPSESSID(和其他cookie)将被设置。