Skip to content
Snippets Groups Projects
Commit a8c80c52 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms Committed by David Siegfried
Browse files

fixes #3204

Closes #3204

Merge request studip/studip!2170
parent 97994ba7
No related branches found
No related tags found
No related merge requests found
......@@ -44,6 +44,35 @@ class CSRFProtection
const AJAX_TOKEN = 'HTTP_X_CSRF_TOKEN';
protected static $storage = null;
/**
* Set a storage to use.
*
* @param $storage
*/
public static function setStorage(&$storage): void
{
self::$storage = &$storage;
}
/**
* Returns a reference to the used storage.
*
* @return array|null
*/
public static function &getStorage()
{
if (!isset(self::$storage)) {
// w/o a session, throw an exception since we cannot use it
if (session_id() === '') {
throw new SessionRequiredException();
}
self::$storage = $_SESSION;
}
return self::$storage;
}
/**
* This checks the request and throws an InvalidSecurityTokenException if
......@@ -118,17 +147,14 @@ class CSRFProtection
*/
public static function token()
{
// w/o a session, throw an exception
if (session_id() === '') {
throw new SessionRequiredException();
}
$storage = &self::getStorage();
// create a token, if there is none
if (!isset($_SESSION[self::TOKEN])) {
$_SESSION[self::TOKEN] = base64_encode(random_bytes(32));
if (!isset($storage[self::TOKEN])) {
$storage[self::TOKEN] = base64_encode(random_bytes(32));
}
return $_SESSION[self::TOKEN];
return $storage[self::TOKEN];
}
/**
......
......@@ -515,8 +515,6 @@ class StudipCoreFormat extends TextFormat
$email = $matches[2];
$domain = $matches[3];
$intern = $domain === $_SERVER['HTTP_HOST'];
return sprintf('<a href="mailto:%1$s">%2$s</a>',
$email,
$link_text
......@@ -567,6 +565,7 @@ class StudipCoreFormat extends TextFormat
$intern = false;
if (
in_array($pu['scheme'], ['http', 'https'])
&& isset($_SERVER['HTTP_HOST'])
&& (
!isset($pu['host'])
|| $pu['host'] === $_SERVER['HTTP_HOST']
......
......@@ -83,6 +83,7 @@ class StudipPDO extends PDO
// split string into parts at quotes and backslash
$parts = preg_split('/([\\\\"\'])/', $statement, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$result = '';
$quote_chr = null;
for ($part = current($parts); $part !== false; $part = next($parts)) {
// inside quotes, "" is ", '' is ' and \x is x
......
......@@ -500,8 +500,8 @@ class Visibility
*/
private static function getUser(&$user)
{
if ($user == null) {
$user = $GLOBALS['user']->user_id;
if (!$user && User::findCurrent()) {
$user = User::findCurrent()->id;
}
}
......
......@@ -130,7 +130,7 @@ class CronjobSchedule extends SimpleORMap
}
if (in_array($type, ['after_initialize', 'after_store']) && is_string($this->parameters)) {
$parameters = json_decode($this->parameters, true) ?: [];
if ($this->task->valid) {
if ($this->task && $this->task->valid) {
$default_parameters = $this->task->extractDefaultParameters();
foreach ($default_parameters as $key => $value) {
if (!isset($parameters[$key])) {
......
......@@ -863,7 +863,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
if (is_array($id_or_object)) {
$pk = static::pk();
$key_values = [];
foreach($pk as $key) {
foreach ($pk as $key) {
if (array_key_exists($key, $id_or_object)) {
$key_values[] = $id_or_object[$key];
}
......@@ -874,6 +874,8 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
} else {
$id = $key_values;
}
} else {
$id = null;
}
} else {
$id = $id_or_object;
......
......@@ -294,9 +294,9 @@ function isLinkIntern($url) {
return true;
}
return in_array($pum['scheme'] ?? null, ['https', 'http', NULL], true)
&& in_array($pum['host'] ?? null, [$_SERVER['SERVER_NAME'], NULL], true)
&& in_array($pum['port'] ?? null, [$_SERVER['SERVER_PORT'], NULL], true)
return in_array($pum['scheme'] ?? null, ['https', 'http', null], true)
&& in_array($pum['host'] ?? null, [$_SERVER['SERVER_NAME'] ?? null, null], true)
&& in_array($pum['port'] ?? null, [$_SERVER['SERVER_PORT'] ?? null, null], true)
&& mb_strpos($pum['path'] ?? '', $GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP']) === 0;
}
......
......@@ -12,27 +12,18 @@
class CSRFProtectionTokenTest extends \Codeception\Test\Unit
{
private $original_session;
use CsrfProtectionSessionTrait;
function setUp(): void
{
if (session_id() === '') {
session_id("test-session");
}
$this->original_session = $_SESSION;
$_SESSION = [];
}
function tearDown(): void
{
$_SESSION = $this->original_session;
$this->initializeTokenStorage();
}
function testTokenGeneration()
{
$this->assertEquals(sizeof($_SESSION), 0);
$this->assertEquals(count($this->storage), 0);
CSRFProtection::token();
$this->assertEquals(sizeof($_SESSION), 1);
$this->assertEquals(count($this->storage), 1);
}
function testTokenIdentity()
......@@ -44,7 +35,7 @@ class CSRFProtectionTokenTest extends \Codeception\Test\Unit
{
$token1 = CSRFProtection::token();
$_SESSION = [];
$this->storage = [];
$token2 = CSRFProtection::token();
......@@ -66,16 +57,17 @@ class CSRFProtectionTokenTest extends \Codeception\Test\Unit
class CSRFRequestTest extends \Codeception\Test\Unit
{
use CsrfProtectionSessionTrait;
private $original_state;
private $token;
function setUp(): void
{
if (session_id() === '') {
session_id("test-session");
}
$this->original_state = [$_SESSION, $_POST, $_SERVER];
$_SESSION = [];
$this->initializeTokenStorage();
$this->original_state = [$_POST, $_SERVER];
$_POST = [];
$this->token = CSRFProtection::token();
$_SERVER['HTTP_X_REQUESTED_WITH'] = null;
......@@ -83,7 +75,7 @@ class CSRFRequestTest extends \Codeception\Test\Unit
function tearDown(): void
{
list($_SESSION, $_POST, $_SERVER) = $this->original_state;
[$_POST, $_SERVER] = $this->original_state;
}
function testInvalidUnsafeRequest()
......@@ -96,7 +88,7 @@ class CSRFRequestTest extends \Codeception\Test\Unit
function testValidUnsafeRequest()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST['security_token'] = $this->token;
$_POST[CSRFProtection::TOKEN] = $this->token;
CSRFProtection::verifyUnsafeRequest();
$this->assertTrue(true);
}
......@@ -134,3 +126,13 @@ class CSRFRequestTest extends \Codeception\Test\Unit
$this->assertTrue(true);
}
}
trait CsrfProtectionSessionTrait
{
protected $storage = [];
protected function initializeTokenStorage()
{
CSRFProtection::setStorage($this->storage);
}
}
......@@ -58,7 +58,7 @@ class MigrationTest extends \Codeception\Test\Unit
public function get($branch = 0)
{
return $this->versions[$branch];
return $this->versions[$branch] ?? 0;
}
public function set($version, $branch = 0)
......
......@@ -101,6 +101,7 @@ function markupList($markup, $matches)
$rows = explode("\n", rtrim($matches[0]));
$indent = 0;
$result = '';
foreach ($rows as $row) {
list($level, $text) = explode(' ', $row, 2);
$level = mb_strlen($level);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment