Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions components/ILIAS/HTTP/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,21 +215,23 @@ The project is also actively maintained.
The http-message package contains the specified interfaces of the php-fig which defined psr-7.

# DropInReplacements
With ILIAS 8, the Technical Board has decided to replace the [`Superglobals`](https://www.php.net/manual/en/language.variables.superglobals.php)
`$_GET`, `$_POST`, `$_COOKIE` and `$_REQUEST` with so called `SuperGlobalDropInReplacement` instances.
These are `ArrayAccess` wrappers for the respective `Superglobals`. They contain the [`Refinery`](../Refinery/README.md)
and run values on readout through the `->kindlyTo()->string()` `transformation` respectively.
Furthermore, the `SuperGlobalDropInReplacement` should prevent that values in the `Superglobals` are manually
assigned or modified/overwritten, because this violates the immutability of these values in the HTTP request.
The general replacement of the `Superglobals` for some 3rd-Party-Libraries however leads to problems, because these
require an `array` and no `ArrayAccess` object (currently known for `SimpleSAMLphp`). Therefore, there is the
possibility to override the `Superglobals` via an ini setting in the `client.ini.php` file.
With ILIAS 8, the Technical Board decided to replace the [`Superglobals`](https://www.php.net/manual/en/language.variables.superglobals.php)
`$_GET`, `$_POST`, `$_COOKIE` and `$_REQUEST` with so-called `SuperGlobalDropInReplacement` instances.
These are `ArrayAccess` wrappers for the respective `Superglobals`. They use the [`Refinery`](../Refinery/README.md)
to sanitize values on readout via the `->kindlyTo()->string()` transformation.
`SuperGlobalDropInReplacement` also prevents values in the `Superglobals` from being manually assigned or
overwritten, since this would violate the immutability of HTTP request values.
Globally replacing the `Superglobals` causes problems with some third-party libraries that require a plain
`array` rather than an `ArrayAccess` object (currently known for `SimpleSAMLphp`). Therefore, the replacement
can be disabled via an ini setting in `client.ini.php`.

As of ILIAS 11, this setting is only applied when `DEVMODE` is enabled.

```
[server]
prevent_super_global_replacement = 1
```

Furthermore, the `SuperGlobalDropInReplacement` behave in such a way when `DEVMODE` is enabled that overwriting a value
Furthermore, the `SuperGlobalDropInReplacement` behave in such a way that overwriting a value
in one of the `Superglobals` leads to a `\OutOfBoundsException`.

Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@
*/
class SuperGlobalDropInReplacement extends KeyValueAccess
{
public function __construct(Factory $factory, array $raw_values, private bool $throwOnValueAssignment = false)
public function __construct(Factory $factory, array $raw_values)
{
parent::__construct($raw_values, $factory->kindlyTo()->string());
}

#[\Override]
public function offsetSet(mixed $offset, mixed $value): void
{
if ($this->throwOnValueAssignment) {
throw new OutOfBoundsException("Modifying global Request-Array such as \$_GET is not allowed!");
}
throw new OutOfBoundsException("Modifying global Request-Array such as \$_GET is not allowed!");

parent::offsetSet($offset, $value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,11 @@ private function getRefinery(): Refinery
);
}

public function testValueCanBeAssignedIfSuperGlobalIsMutable(): void
{
$super_global = new SuperGlobalDropInReplacement($this->getRefinery(), ['foo' => 'bar']);
$super_global['foo'] = 'phpunit';

$this->assertEquals('phpunit', $super_global['foo']);
}

public function testExceptionIsRaisedIfValueIsAssignedButSuperGlobalIsImmutable(): void
public function testExceptionIsRaisedIfValueIsAssigned(): void
{
$this->expectException(OutOfBoundsException::class);

$super_global = new SuperGlobalDropInReplacement($this->getRefinery(), ['foo' => 'bar'], true);
$super_global = new SuperGlobalDropInReplacement($this->getRefinery(), ['foo' => 'bar']);
$super_global['foo'] = 'phpunit';
}
}
16 changes: 8 additions & 8 deletions components/ILIAS/Init/classes/class.ilInitialisation.php
Original file line number Diff line number Diff line change
Expand Up @@ -1539,17 +1539,17 @@ protected static function replaceSuperGlobals(\ILIAS\DI\Container $container): v
$client_ini = $container['ilClientIniFile'];

$replace_super_globals = (
!$client_ini->variableExists('server', 'prevent_super_global_replacement') ||
!(bool) $client_ini->readVariable('server', 'prevent_super_global_replacement')
defined('DEVMODE') && DEVMODE && (
!$client_ini->variableExists('server', 'prevent_super_global_replacement') ||
!(bool) $client_ini->readVariable('server', 'prevent_super_global_replacement')
)
);

if ($replace_super_globals) {
$throwOnValueAssignment = defined('DEVMODE') && DEVMODE;

$_GET = new SuperGlobalDropInReplacement($container['refinery'], $_GET, $throwOnValueAssignment);
$_POST = new SuperGlobalDropInReplacement($container['refinery'], $_POST, $throwOnValueAssignment);
$_COOKIE = new SuperGlobalDropInReplacement($container['refinery'], $_COOKIE, $throwOnValueAssignment);
$_REQUEST = new SuperGlobalDropInReplacement($container['refinery'], $_REQUEST, $throwOnValueAssignment);
$_GET = new SuperGlobalDropInReplacement($container['refinery'], $_GET);
$_POST = new SuperGlobalDropInReplacement($container['refinery'], $_POST);
$_COOKIE = new SuperGlobalDropInReplacement($container['refinery'], $_COOKIE);
$_REQUEST = new SuperGlobalDropInReplacement($container['refinery'], $_REQUEST);
}
}

Expand Down
2 changes: 1 addition & 1 deletion components/ILIAS/Saml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ See:
## ILIAS Configuration

Please change your ILIAS configuration according to the `Superglobal` behaviour described in
the [`HTTP README`](../HTTP/README.md#dropinreplacements)
the [`HTTP README`](../HTTP/README.md#dropinreplacements) when running ILIAS in `DEVMODE`.

## Config Changes in ILIAS 9

Expand Down
Loading