Make authenticated cookies lax

This protects our cookies a bit more. It makes sure that when a 3rdparty
websites embededs a public alendar for example. That all the users see
this in anonymous mode there.

It adds a small helper function.

In the future we can think about protecting other cookies like this as
well. But for now this is sufficient to not have the user logged in at
all when doing 3rdparty requests.

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2018-09-28 15:06:48 +02:00
parent db50e11edf
commit 9a7265babf
No known key found for this signature in database
GPG Key ID: F941078878347C0C
4 changed files with 108 additions and 4 deletions

View File

@ -796,6 +796,7 @@ return array(
'OC\\Http\\Client\\Client' => $baseDir . '/lib/private/Http/Client/Client.php',
'OC\\Http\\Client\\ClientService' => $baseDir . '/lib/private/Http/Client/ClientService.php',
'OC\\Http\\Client\\Response' => $baseDir . '/lib/private/Http/Client/Response.php',
'OC\\Http\\CookieHelper' => $baseDir . '/lib/private/Http/CookieHelper.php',
'OC\\Installer' => $baseDir . '/lib/private/Installer.php',
'OC\\IntegrityCheck\\Checker' => $baseDir . '/lib/private/IntegrityCheck/Checker.php',
'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException' => $baseDir . '/lib/private/IntegrityCheck/Exceptions/InvalidSignatureException.php',

View File

@ -826,6 +826,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Http\\Client\\Client' => __DIR__ . '/../../..' . '/lib/private/Http/Client/Client.php',
'OC\\Http\\Client\\ClientService' => __DIR__ . '/../../..' . '/lib/private/Http/Client/ClientService.php',
'OC\\Http\\Client\\Response' => __DIR__ . '/../../..' . '/lib/private/Http/Client/Response.php',
'OC\\Http\\CookieHelper' => __DIR__ . '/../../..' . '/lib/private/Http/CookieHelper.php',
'OC\\Installer' => __DIR__ . '/../../..' . '/lib/private/Installer.php',
'OC\\IntegrityCheck\\Checker' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Checker.php',
'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Exceptions/InvalidSignatureException.php',

View File

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Http;
class CookieHelper {
const SAMESITE_NONE = 0;
const SAMESITE_LAX = 1;
const SAMESITE_STRICT = 2;
public static function setCookie(string $name,
string $value = '',
int $maxAge = 0,
string $path = '',
string $domain = '',
bool $secure = false,
bool $httponly = false,
int $samesite = self::SAMESITE_NONE) {
$header = sprintf(
'Set-Cookie: %s=%s',
$name,
urlencode($value)
);
if ($path !== '') {
$header .= sprintf('; Path=%s', $path);
}
if ($domain !== '') {
$header .= sprintf('; Domain=%s', $domain);
}
if ($maxAge > 0) {
$header .= sprintf('; Max-Age=%d', $maxAge);
}
if ($secure) {
$header .= '; Secure';
}
if ($httponly) {
$header .= '; HttpOnly';
}
if ($samesite === self::SAMESITE_LAX) {
$header .= '; SameSite=Lax';
} else if ($samesite === self::SAMESITE_STRICT) {
$header .= '; SameSite=Strict';
}
header($header, false);
}
}

View File

@ -869,11 +869,38 @@ class Session implements IUserSession, Emitter {
$webRoot = '/';
}
$expires = $this->timeFactory->getTime() + $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
setcookie('nc_username', $username, $expires, $webRoot, '', $secureCookie, true);
setcookie('nc_token', $token, $expires, $webRoot, '', $secureCookie, true);
$maxAge = $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
\OC\Http\CookieHelper::setCookie(
'nc_username',
$username,
$maxAge,
$webRoot,
'',
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
);
\OC\Http\CookieHelper::setCookie(
'nc_token',
$token,
$maxAge,
$webRoot,
'',
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
);
try {
setcookie('nc_session_id', $this->session->getId(), $expires, $webRoot, '', $secureCookie, true);
\OC\Http\CookieHelper::setCookie(
'nc_session_id',
$this->session->getId(),
$maxAge,
$webRoot,
'',
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
);
} catch (SessionNotAvailableException $ex) {
// ignore
}