PHP setcookie"SameSite = Strict"?

Lau*_*aes 30 php security cookies

我最近在属性"Same Site"上阅读了"RFC 6265",我看了一些在2016年4月讨论过的文章,为Chrome 51和Opera 39实现了"同站点"属性...

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

参考:

Mar*_*yan 32

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
)
Run Code Online (Sandbox Code Playgroud)

在此处查看更多内容 - PHP RFC:相同的站点Cookie

2.对于PHP <v7.3

您可以使用以下解决方案/解决方法之一,具体取决于您的代码库/需求

2.1使用Apache配置设置SameSite cookie

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

Header always edit Set-Cookie (.*) "$1; SameSite=Lax"
Run Code Online (Sandbox Code Playgroud)

这将使用SameSite=Laxflag 更新所有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";
}
Run Code Online (Sandbox Code Playgroud)

同样在这里,这也将使用SameSite=Laxflag 更新所有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
Run Code Online (Sandbox Code Playgroud)

所以我们可以用header方法设置cookie

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

实际上,Symphony并不是在等待PHP 7.3并且已经在幕后工作,请看这里

你也可以在Laravel中使用它,因为Laravel使用Symphony的Symfony\Component\HttpFoundation\Cookie

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

setcookie('cookie-name', '1', 0, '/; samesite=strict');
Run Code Online (Sandbox Code Playgroud)

小心这个,它是PHP setcookie方法中的已知错误,已在PHP7.3版本中解决,请参阅此处 - https://github.com/php/php-src/commit/5cb825df7251aeb28b297f071c35b227a3949f01

  • 看起来这不是PHP 7.3+中`setcookie`(和`setr​​awcookie`)的正确方法签名,传递了一组选项作为第三个参数,其中一个称为`samesite`。参见https://github.com/php/php-src/blob/PHP-7.3/UPGRADING#L350 (2认同)

Ste*_*fen 24

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

看起来您可以滥用PHP的"setcookie"函数的"路径"或"域"参数来隐藏SameSite属性,因为PHP不会以分号转义:

setcookie('samesite-test', '1', 0, '/; samesite=strict');
Run Code Online (Sandbox Code Playgroud)

然后PHP发送以下HTTP标头:

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

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

  • 看起来这可能很快就会停止工作(可能在 PHP 7.3 中):https://github.com/php/php-src/commit/5cb825df7251aeb28b297f071c35b227a3949f01 (4认同)

小智 23

根据上面Steffen 的回答,这是我用来支持 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 
 *
 * @see https://www.php.net/manual/en/function.setcookie.php
 *
 * @param string $name
 * @param string $value
 * @param int $expire
 * @param string $path
 * @param string $domain
 * @param bool $secure
 * @param bool $httponly
 * @param string $samesite
 * @return void
 */
function setCookieSameSite(
    string $name, string $value,
    int $expire, string $path, string $domain,
    bool $secure, bool $httponly, string $samesite = 'None'
): void {
    if (PHP_VERSION_ID < 70300) {
        setcookie($name, $value, $expire, $path . '; samesite=' . $samesite, $domain, $secure, $httponly);
        return;
    }
    setcookie($name, $value, [
        'expires' => $expire,
        'path' => $path,
        'domain' => $domain,
        'samesite' => $samesite,
        'secure' => $secure,
        'httponly' => $httponly,
    ]);
}
Run Code Online (Sandbox Code Playgroud)