mirror of
https://github.com/nextcloud/all-in-one.git
synced 2025-12-21 06:56:57 +00:00
Initial import
This commit is contained in:
commit
2295a33590
884 changed files with 93939 additions and 0 deletions
22
php/vendor/slim/csrf/CHANGELOG.md
vendored
Normal file
22
php/vendor/slim/csrf/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Change Log
|
||||
|
||||
## 2016-08-14
|
||||
|
||||
Now supports "persistence mode", to persist a single CSRF name/value pair throughout the life of a user's session. Added the following methods:
|
||||
|
||||
- `protected getLastKeyPair` - gets the most recently generated key/value pair from storage.
|
||||
- `protected loadLastKeyPair` - gets the most recently generated key/value pair from storage, and assign it to `$this->keyPair`.
|
||||
- `public setPersistentTokenMode`
|
||||
- `public getPersistentTokenMode`
|
||||
|
||||
Note that if CSRF token validation fails, then the token should be renewed regardless of the persistence setting.
|
||||
|
||||
The methods `getTokenName` and `getTokenValue` now return `null` if `$this->keyPair` has not yet been set.
|
||||
|
||||
### Tests added:
|
||||
|
||||
- `testPersistenceModeTrueBetweenRequestsArray` - Token should persist between requests after initial creation, when stored in an array.
|
||||
- `testPersistenceModeTrueBetweenRequestsArrayAccess` - Token should persist between requests after initial creation, when stored in an ArrayObject.
|
||||
- `testPersistenceModeFalseBetweenRequestsArray` - Token should be changed between requests, when stored in an array.
|
||||
- `testPersistenceModeFalseBetweenRequestsArrayAccess` - Token should be changed between requests, when stored in an ArrayObject.
|
||||
- `testUpdateAfterInvalidTokenWithPersistenceModeTrue` - New token should be generated after an invalid request, even if persistence mode is enabled.
|
||||
19
php/vendor/slim/csrf/LICENSE.md
vendored
Normal file
19
php/vendor/slim/csrf/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012-2015 Josh Lockhart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
41
php/vendor/slim/csrf/composer.json
vendored
Normal file
41
php/vendor/slim/csrf/composer.json
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "slim/csrf",
|
||||
"type": "library",
|
||||
"description": "Slim Framework 4 CSRF protection PSR-15 middleware",
|
||||
"keywords": ["slim","framework","middleware","csrf"],
|
||||
"homepage": "http://slimframework.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "hello@joshlockhart.com",
|
||||
"homepage": "http://joshlockhart.com"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/prophecy": "^1.12",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\Csrf\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Slim\\Csrf\\Tests\\": "tests"
|
||||
}
|
||||
}
|
||||
}
|
||||
479
php/vendor/slim/csrf/src/Guard.php
vendored
Normal file
479
php/vendor/slim/csrf/src/Guard.php
vendored
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim Framework (https://slimframework.com)
|
||||
*
|
||||
* @license https://github.com/slimphp/Slim-Csrf/blob/master/LICENSE.md (MIT License)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Slim\Csrf;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Exception;
|
||||
use Iterator;
|
||||
use Psr\Http\Message\ResponseFactoryInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class Guard implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @var ResponseFactoryInterface
|
||||
*/
|
||||
protected $responseFactory;
|
||||
|
||||
/**
|
||||
* Prefix for CSRF parameters (omit trailing "_" underscore)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* CSRF storage
|
||||
*
|
||||
* Should be either an array or an object. If an object is used, then it must
|
||||
* implement ArrayAccess and should implement Countable and Iterator
|
||||
* if storage limit enforcement is required.
|
||||
*
|
||||
* @var array|ArrayAccess
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Number of elements to store in the storage array
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $storageLimit;
|
||||
|
||||
/**
|
||||
* CSRF Strength
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $strength;
|
||||
|
||||
/**
|
||||
* Callable to be executed if the CSRF validation fails
|
||||
* It must return a ResponseInterface
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
protected $failureHandler;
|
||||
|
||||
/**
|
||||
* Determines whether or not we should persist the token throughout the duration of the user's session.
|
||||
*
|
||||
* For security, Slim-Csrf will *always* reset the token if there is a validation error.
|
||||
* @var bool True to use the same token throughout the session (unless there is a validation error),
|
||||
* false to get a new token with each request.
|
||||
*/
|
||||
protected $persistentTokenMode;
|
||||
|
||||
/**
|
||||
* Stores the latest key-pair generated by the class
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $keyPair = null;
|
||||
|
||||
/**
|
||||
* @param ResponseFactoryInterface $responseFactory
|
||||
* @param string $prefix
|
||||
* @param null|array|ArrayAccess $storage
|
||||
* @param null|callable $failureHandler
|
||||
* @param integer $storageLimit
|
||||
* @param integer $strength
|
||||
* @param boolean $persistentTokenMode
|
||||
* @throws RuntimeException if the session cannot be found
|
||||
*/
|
||||
public function __construct(
|
||||
ResponseFactoryInterface $responseFactory,
|
||||
string $prefix = 'csrf',
|
||||
&$storage = null,
|
||||
?callable $failureHandler = null,
|
||||
int $storageLimit = 200,
|
||||
int $strength = 16,
|
||||
bool $persistentTokenMode = false
|
||||
) {
|
||||
if ($strength < 16) {
|
||||
throw new RuntimeException('CSRF middleware instantiation failed. Minimum strength is 16.');
|
||||
}
|
||||
|
||||
$this->responseFactory = $responseFactory;
|
||||
$this->prefix = rtrim($prefix, '_');
|
||||
$this->strength = $strength;
|
||||
|
||||
$this->setStorage($storage);
|
||||
$this->setFailureHandler($failureHandler);
|
||||
$this->setStorageLimit($storageLimit);
|
||||
$this->setPersistentTokenMode($persistentTokenMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|array|ArrayAccess $storage
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function setStorage(&$storage = null): self
|
||||
{
|
||||
if (is_array($storage)
|
||||
|| ($storage instanceof ArrayAccess
|
||||
&& $storage instanceof Countable
|
||||
&& $storage instanceof Iterator
|
||||
)
|
||||
) {
|
||||
$this->storage = &$storage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
throw new RuntimeException(
|
||||
'Invalid CSRF storage. ' .
|
||||
'Use session_start() before instantiating the Guard middleware or provide array storage.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!array_key_exists($this->prefix, $_SESSION) || !is_array($_SESSION[$this->prefix])) {
|
||||
$_SESSION[$this->prefix] = [];
|
||||
}
|
||||
|
||||
$this->storage = &$_SESSION[$this->prefix];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|null $failureHandler Value to set
|
||||
* @return self
|
||||
*/
|
||||
public function setFailureHandler(?callable $failureHandler): self
|
||||
{
|
||||
$this->failureHandler = $failureHandler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $persistentTokenMode True to use the same token throughout the session
|
||||
* (unless there is a validation error), false to get a new token with each request.
|
||||
* @return self
|
||||
*/
|
||||
public function setPersistentTokenMode(bool $persistentTokenMode): self
|
||||
{
|
||||
$this->persistentTokenMode = $persistentTokenMode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $storageLimit Value to set
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStorageLimit(int $storageLimit): self
|
||||
{
|
||||
$this->storageLimit = $storageLimit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function createToken(): string
|
||||
{
|
||||
return bin2hex(random_bytes($this->strength));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generateToken(): array
|
||||
{
|
||||
// Generate new CSRF token
|
||||
$name = uniqid($this->prefix);
|
||||
$value = $this->createToken();
|
||||
$this->saveTokenToStorage($name, $value);
|
||||
|
||||
|
||||
$this->keyPair = [
|
||||
$this->getTokenNameKey() => $name,
|
||||
$this->getTokenValueKey() => $value
|
||||
];
|
||||
|
||||
return $this->keyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate CSRF token from current request against token value
|
||||
* stored in $_SESSION or user provided storage
|
||||
*
|
||||
* @param string $name CSRF name
|
||||
* @param string $value CSRF token value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateToken(string $name, string $value): bool
|
||||
{
|
||||
if (!isset($this->storage[$name])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = $this->storage[$name];
|
||||
|
||||
if (function_exists('hash_equals')) {
|
||||
return hash_equals($token, $value);
|
||||
}
|
||||
|
||||
return $token === $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTokenName(): ?string
|
||||
{
|
||||
return $this->keyPair[$this->getTokenNameKey()] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTokenValue(): ?string
|
||||
{
|
||||
return $this->keyPair[$this->getTokenValueKey()] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTokenNameKey(): string
|
||||
{
|
||||
return $this->prefix . '_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTokenValueKey(): string
|
||||
{
|
||||
return $this->prefix . '_value';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getPersistentTokenMode(): bool
|
||||
{
|
||||
return $this->persistentTokenMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]|null
|
||||
*/
|
||||
protected function getLastKeyPair(): ?array
|
||||
{
|
||||
if (
|
||||
(is_array($this->storage) && empty($this->storage))
|
||||
|| ($this->storage instanceof Countable && count($this->storage) < 1)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = null;
|
||||
$value = null;
|
||||
if (is_array($this->storage)) {
|
||||
end($this->storage);
|
||||
$name = key($this->storage);
|
||||
$value = $this->storage[$name];
|
||||
reset($this->storage);
|
||||
} elseif ($this->storage instanceof Iterator) {
|
||||
$this->storage->rewind();
|
||||
while ($this->storage->valid()) {
|
||||
$name = $this->storage->key();
|
||||
$value = $this->storage->current();
|
||||
$this->storage->next();
|
||||
}
|
||||
$this->storage->rewind();
|
||||
}
|
||||
|
||||
return $name !== null && $value !== null
|
||||
? [
|
||||
$this->getTokenNameKey() => $name,
|
||||
$this->getTokenValueKey() => $value
|
||||
]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the most recent key pair in storage.
|
||||
*
|
||||
* @return bool `true` if there was a key pair to load in storage, false otherwise.
|
||||
*/
|
||||
protected function loadLastKeyPair(): bool
|
||||
{
|
||||
return (bool) $this->keyPair = $this->getLastKeyPair();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name CSRF token name
|
||||
* @param string $value CSRF token value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function saveTokenToStorage(string $name, string $value): void
|
||||
{
|
||||
$this->storage[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove token from storage
|
||||
*
|
||||
* @param string $name CSRF token name
|
||||
*/
|
||||
public function removeTokenFromStorage(string $name): void
|
||||
{
|
||||
$this->storage[$name] = '';
|
||||
unset($this->storage[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the oldest tokens from the storage array so that there
|
||||
* are never more than storageLimit tokens in the array.
|
||||
*
|
||||
* This is required as a token is generated every request and so
|
||||
* most will never be used.
|
||||
*/
|
||||
protected function enforceStorageLimit(): void
|
||||
{
|
||||
if ($this->storageLimit === 0
|
||||
|| (
|
||||
!is_array($this->storage)
|
||||
&& !($this->storage instanceof Countable && $this->storage instanceof Iterator)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($this->storage)) {
|
||||
while (count($this->storage) > $this->storageLimit) {
|
||||
array_shift($this->storage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->storage instanceof Iterator) {
|
||||
while (count($this->storage) > $this->storageLimit) {
|
||||
$this->storage->rewind();
|
||||
unset($this->storage[$this->storage->key()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
*
|
||||
* @return ServerRequestInterface
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function appendNewTokenToRequest(ServerRequestInterface $request): ServerRequestInterface
|
||||
{
|
||||
$token = $this->generateToken();
|
||||
return $this->appendTokenToRequest($request, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param array $pair
|
||||
*
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
protected function appendTokenToRequest(ServerRequestInterface $request, array $pair): ServerRequestInterface
|
||||
{
|
||||
$name = $this->getTokenNameKey();
|
||||
$value = $this->getTokenValueKey();
|
||||
return $request
|
||||
->withAttribute($name, $pair[$name])
|
||||
->withAttribute($value, $pair[$value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$body = $request->getParsedBody();
|
||||
$name = null;
|
||||
$value = null;
|
||||
|
||||
if (is_array($body)) {
|
||||
$name = $body[$this->getTokenNameKey()] ?? null;
|
||||
$value = $body[$this->getTokenValueKey()] ?? null;
|
||||
}
|
||||
|
||||
if (in_array($request->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) {
|
||||
$isValid = $this->validateToken((string) $name, (string) $value);
|
||||
if ($isValid && !$this->persistentTokenMode) {
|
||||
// successfully validated token, so delete it if not in persistentTokenMode
|
||||
$this->removeTokenFromStorage($name);
|
||||
}
|
||||
|
||||
if ($name === null || $value === null || !$isValid) {
|
||||
$request = $this->appendNewTokenToRequest($request);
|
||||
return $this->handleFailure($request, $handler);
|
||||
}
|
||||
} else {
|
||||
// Method is GET/OPTIONS/HEAD/etc, so do not accept the token in the body of this request
|
||||
if ($name !== null) {
|
||||
return $this->handleFailure($request, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->persistentTokenMode || !$this->loadLastKeyPair()) {
|
||||
$request = $this->appendNewTokenToRequest($request);
|
||||
} else {
|
||||
$pair = $this->loadLastKeyPair() ? $this->keyPair : $this->generateToken();
|
||||
$request = $this->appendTokenToRequest($request, $pair);
|
||||
}
|
||||
|
||||
$this->enforceStorageLimit();
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function handleFailure(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if (!is_callable($this->failureHandler)) {
|
||||
$response = $this->responseFactory->createResponse();
|
||||
$body = $response->getBody();
|
||||
$body->write('Failed CSRF check!');
|
||||
return $response
|
||||
->withStatus(400)
|
||||
->withHeader('Content-Type', 'text/plain')
|
||||
->withBody($body);
|
||||
}
|
||||
|
||||
return call_user_func($this->failureHandler, $request, $handler);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue