mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
fix: add missing URI Security and Conig\App::$permittedURIChars
This commit is contained in:
parent
7f0cab1e6c
commit
4d6b45b769
@ -59,6 +59,30 @@ class App extends BaseConfig
|
||||
*/
|
||||
public string $uriProtocol = 'REQUEST_URI';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Allowed URL Characters
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This lets you specify which characters are permitted within your URLs.
|
||||
| When someone tries to submit a URL with disallowed characters they will
|
||||
| get a warning message.
|
||||
|
|
||||
| As a security measure you are STRONGLY encouraged to restrict URLs to
|
||||
| as few characters as possible.
|
||||
|
|
||||
| By default, only these are allowed: `a-z 0-9~%.:_-`
|
||||
|
|
||||
| Set an empty string to allow all characters -- but only if you are insane.
|
||||
|
|
||||
| The configured value is actually a regular expression character group
|
||||
| and it will be used as: '/\A[<permittedURIChars>]+\z/iu'
|
||||
|
|
||||
| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
|
||||
|
|
||||
*/
|
||||
public string $permittedURIChars = 'a-z 0-9~%.:_\-';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Default Locale
|
||||
|
28
system/HTTP/Exceptions/BadRequestException.php
Normal file
28
system/HTTP/Exceptions/BadRequestException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CodeIgniter\HTTP\Exceptions;
|
||||
|
||||
use CodeIgniter\Exceptions\HTTPExceptionInterface;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* 400 Bad Request
|
||||
*/
|
||||
class BadRequestException extends RuntimeException implements HTTPExceptionInterface
|
||||
{
|
||||
/**
|
||||
* HTTP status code for Bad Request
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 400; // @phpstan-ignore-line
|
||||
}
|
@ -13,6 +13,7 @@ namespace CodeIgniter\Router;
|
||||
|
||||
use Closure;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\Exceptions\BadRequestException;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\Request;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
@ -120,11 +121,23 @@ class Router implements RouterInterface
|
||||
|
||||
protected ?AutoRouterInterface $autoRouter = null;
|
||||
|
||||
/**
|
||||
* Permitted URI chars
|
||||
*
|
||||
* The default value is `''` (do not check) for backward compatibility.
|
||||
*/
|
||||
protected string $permittedURIChars = '';
|
||||
|
||||
/**
|
||||
* Stores a reference to the RouteCollection object.
|
||||
*/
|
||||
public function __construct(RouteCollectionInterface $routes, ?Request $request = null)
|
||||
{
|
||||
$config = config(App::class);
|
||||
if (isset($config->permittedURIChars)) {
|
||||
$this->permittedURIChars = $config->permittedURIChars;
|
||||
}
|
||||
|
||||
$this->collection = $routes;
|
||||
|
||||
// These are only for auto-routing
|
||||
@ -179,6 +192,8 @@ class Router implements RouterInterface
|
||||
// Decode URL-encoded string
|
||||
$uri = urldecode($uri);
|
||||
|
||||
$this->checkDisallowedChars($uri);
|
||||
|
||||
// Restart filterInfo
|
||||
$this->filterInfo = null;
|
||||
$this->filtersInfo = [];
|
||||
@ -676,4 +691,20 @@ class Router implements RouterInterface
|
||||
|
||||
$this->matchedRouteOptions = $this->collection->getRoutesOptions($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks disallowed characters
|
||||
*/
|
||||
private function checkDisallowedChars(string $uri): void
|
||||
{
|
||||
foreach (explode('/', $uri) as $segment) {
|
||||
if ($segment !== '' && $this->permittedURIChars !== ''
|
||||
&& preg_match('/\A[' . $this->permittedURIChars . ']+\z/iu', $segment) !== 1
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
'The URI you submitted has disallowed characters: "' . $segment . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,12 @@ namespace CodeIgniter\Router;
|
||||
|
||||
use CodeIgniter\Config\Services;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\Exceptions\BadRequestException;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\IncomingRequest;
|
||||
use CodeIgniter\Router\Exceptions\RouterException;
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use Config\App;
|
||||
use Config\Modules;
|
||||
use Config\Routing;
|
||||
use Tests\Support\Filters\Customfilter;
|
||||
@ -87,6 +89,16 @@ final class RouterTest extends CIUnitTestCase
|
||||
$router->handle('0');
|
||||
}
|
||||
|
||||
public function testNotPermittedChars(): void
|
||||
{
|
||||
$router = new Router($this->collection, $this->request);
|
||||
|
||||
$this->expectException(BadRequestException::class);
|
||||
$this->expectExceptionMessage('The URI you submitted has disallowed characters: "<a>"');
|
||||
|
||||
$router->handle('test/%3Ca%3E');
|
||||
}
|
||||
|
||||
public function testURIMapsToController(): void
|
||||
{
|
||||
$router = new Router($this->collection, $this->request);
|
||||
@ -783,6 +795,9 @@ final class RouterTest extends CIUnitTestCase
|
||||
*/
|
||||
public function testRegularExpressionWithUnicode(): void
|
||||
{
|
||||
$config = config(App::class);
|
||||
$config->permittedURIChars = 'a-z 0-9~%.:_\-\x{0980}-\x{09ff}';
|
||||
|
||||
$this->collection->get('news/([a-z0-9\x{0980}-\x{09ff}-]+)', 'News::view/$1');
|
||||
|
||||
$router = new Router($this->collection, $this->request);
|
||||
@ -802,6 +817,9 @@ final class RouterTest extends CIUnitTestCase
|
||||
*/
|
||||
public function testRegularExpressionPlaceholderWithUnicode(): void
|
||||
{
|
||||
$config = config(App::class);
|
||||
$config->permittedURIChars = 'a-z 0-9~%.:_\-\x{0980}-\x{09ff}';
|
||||
|
||||
$this->collection->addPlaceholder('custom', '[a-z0-9\x{0980}-\x{09ff}-]+');
|
||||
$this->collection->get('news/(:custom)', 'News::view/$1');
|
||||
|
||||
|
@ -10,6 +10,15 @@ Release Date: Unreleased
|
||||
:local:
|
||||
:depth: 3
|
||||
|
||||
********
|
||||
SECURITY
|
||||
********
|
||||
|
||||
- **URI Security:** The feature to check if URIs do not contain not permitted
|
||||
strings has been added. This check is equivalent to the URI Security found in
|
||||
CodeIgniter 3. This is enabled by default, but upgraded users need to add
|
||||
a setting to enable it. See :ref:`urls-uri-security` for details.
|
||||
|
||||
********
|
||||
BREAKING
|
||||
********
|
||||
|
@ -38,6 +38,7 @@ OWASP recommendations
|
||||
CodeIgniter provisions
|
||||
======================
|
||||
|
||||
- :ref:`urls-uri-security`
|
||||
- :ref:`invalidchars` filter
|
||||
- :doc:`../libraries/validation` library
|
||||
- :doc:`HTTP library <../incoming/incomingrequest>` provides for :ref:`input field filtering <incomingrequest-filtering-input-data>` & content metadata
|
||||
|
@ -58,6 +58,39 @@ Route path /blog/news/2022/10 The URI path relative to the Bas
|
||||
Query page=2
|
||||
========== ==================================== =========================================
|
||||
|
||||
.. _urls-uri-security:
|
||||
|
||||
URI Security
|
||||
============
|
||||
|
||||
.. versionadded:: 4.4.7
|
||||
|
||||
.. important::
|
||||
Users upgrading from versions prior to v4.4.7 will need to add the following
|
||||
to **app/Config/App.php** in order to use this feature::
|
||||
|
||||
public string $permittedURIChars = 'a-z 0-9~%.:_\-';
|
||||
|
||||
CodeIgniter is fairly restrictive regarding which characters it allows in your
|
||||
URI strings (Route path) in order to help minimize the possibility that malicious
|
||||
data can be passed to your application. URIs may only contain the following:
|
||||
|
||||
- Alpha-numeric text (latin characters only)
|
||||
- Tilde: ``~``
|
||||
- Percent sign: ``%``
|
||||
- Period: ``.``
|
||||
- Colon: ``:``
|
||||
- Underscore: ``_``
|
||||
- Dash: ``-``
|
||||
- Space: `` ``
|
||||
|
||||
This setting can be changed by ``Config\App::$permittedURIChars``.
|
||||
|
||||
.. note::
|
||||
This check is performed by the ``Router``. The Router takes the URL-encoded
|
||||
value held by the ``SiteURI`` class, decodes it, and then checks that it
|
||||
does not contain not permitted strings.
|
||||
|
||||
.. _urls-remove-index-php:
|
||||
|
||||
Removing the index.php file
|
||||
|
@ -16,6 +16,18 @@ Please refer to the upgrade instructions corresponding to your installation meth
|
||||
Mandatory File Changes
|
||||
**********************
|
||||
|
||||
URI Security
|
||||
============
|
||||
|
||||
The feature to check if URIs do not contain not permitted strings has been added.
|
||||
This check is equivalent to the URI Security found in CodeIgniter 3.
|
||||
|
||||
We recommend you enable this feature. Add the following to **app/Config/App.php**::
|
||||
|
||||
public string $permittedURIChars = 'a-z 0-9~%.:_\-';.
|
||||
|
||||
See :ref:`urls-uri-security` for details.
|
||||
|
||||
Error Files
|
||||
===========
|
||||
|
||||
@ -66,6 +78,9 @@ and it is recommended that you merge the updated versions with your application:
|
||||
Config
|
||||
------
|
||||
|
||||
- app/Config/App.php
|
||||
- The property ``$permittedURIChars`` was added. See :ref:`urls-uri-security`
|
||||
for details.
|
||||
- @TODO
|
||||
|
||||
All Changes
|
||||
|
Loading…
x
Reference in New Issue
Block a user