mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Merge remote-tracking branch 'origin/develop' into 4.5
Conflicts: system/CodeIgniter.php system/Filters/Filters.php system/Language/Language.php system/Router/Router.php
This commit is contained in:
commit
96ce795691
33
CHANGELOG.md
33
CHANGELOG.md
@ -1,5 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
## [v4.4.7](https://github.com/codeigniter4/CodeIgniter4/tree/v4.4.7) (2024-03-29)
|
||||
[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.6...v4.4.7)
|
||||
|
||||
### SECURITY
|
||||
|
||||
* **Language:** *Language class DoS Vulnerability* was fixed. See the
|
||||
[Security advisory](https://github.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-39fp-mqmm-gxj6)
|
||||
for more information.
|
||||
* **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.
|
||||
* **Filters:** A bug where URI paths processed by Filters were not URL-decoded
|
||||
has been fixed.
|
||||
|
||||
### Breaking Changes
|
||||
* fix: Time::difference() DST bug by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8661
|
||||
|
||||
### Fixed Bugs
|
||||
* fix: [Validation] FileRules cause error if getimagesize() returns false by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8592
|
||||
* fix: isWriteType() to recognize CTE; always excluding RETURNING by @markconnellypro in https://github.com/codeigniter4/CodeIgniter4/pull/8599
|
||||
* fix: duplicate Cache-Control header with Session by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8601
|
||||
* fix: [DebugBar] scroll to top by @ddevsr in https://github.com/codeigniter4/CodeIgniter4/pull/8595
|
||||
* fix: Model::shouldUpdate() logic by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8614
|
||||
* fix: esc() for 'raw' context by @Cleric-K in https://github.com/codeigniter4/CodeIgniter4/pull/8633
|
||||
* docs: fix incorrect CURLRequest allow_redirects description by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8653
|
||||
* fix: Model::set() does not accept object by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8670
|
||||
|
||||
### Refactoring
|
||||
* refactor: replace PHP_VERSION by PHP_VERSION_ID by @justbyitself in https://github.com/codeigniter4/CodeIgniter4/pull/8618
|
||||
* refactor: apply early return pattern by @justbyitself in https://github.com/codeigniter4/CodeIgniter4/pull/8621
|
||||
* refactor: move footer info to top in error_exception.php by @kenjis in https://github.com/codeigniter4/CodeIgniter4/pull/8626
|
||||
|
||||
## [v4.4.6](https://github.com/codeigniter4/CodeIgniter4/tree/v4.4.6) (2024-02-24)
|
||||
[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.4.5...v4.4.6)
|
||||
|
||||
|
@ -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
|
||||
|
@ -10,7 +10,7 @@
|
||||
<output>api/build/</output>
|
||||
<cache>api/cache/</cache>
|
||||
</paths>
|
||||
<version number="4.4.6">
|
||||
<version number="4.4.7">
|
||||
<api format="php">
|
||||
<source dsn=".">
|
||||
<path>system</path>
|
||||
|
@ -13428,7 +13428,7 @@ $ignoreErrors[] = [
|
||||
];
|
||||
$ignoreErrors[] = [
|
||||
'message' => '#^Assigning \'GET\' directly on offset \'REQUEST_METHOD\' of \\$_SERVER is discouraged\\.$#',
|
||||
'count' => 35,
|
||||
'count' => 36,
|
||||
'path' => __DIR__ . '/tests/system/Filters/FiltersTest.php',
|
||||
];
|
||||
$ignoreErrors[] = [
|
||||
|
@ -56,7 +56,7 @@ class CodeIgniter
|
||||
/**
|
||||
* The current version of CodeIgniter Framework
|
||||
*/
|
||||
public const CI_VERSION = '4.4.6';
|
||||
public const CI_VERSION = '4.4.7';
|
||||
|
||||
/**
|
||||
* App startup time.
|
||||
@ -456,6 +456,7 @@ class CodeIgniter
|
||||
|
||||
$routeFilters = $this->tryToRouteIt($routes);
|
||||
|
||||
// $uri is URL-encoded.
|
||||
$uri = $this->request->getPath();
|
||||
|
||||
if ($this->enableFilters) {
|
||||
@ -823,6 +824,7 @@ class CodeIgniter
|
||||
// $routes is defined in Config/Routes.php
|
||||
$this->router = Services::router($routes, $this->request);
|
||||
|
||||
// $uri is URL-encoded.
|
||||
$uri = $this->request->getPath();
|
||||
|
||||
$this->outputBufferingStart();
|
||||
|
@ -384,6 +384,9 @@ class Filters
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Decode URL-encoded string
|
||||
$uri = urldecode($uri);
|
||||
|
||||
$oldFilterOrder = config(Feature::class)->oldFilterOrder ?? false;
|
||||
if ($oldFilterOrder) {
|
||||
$this->processGlobals($uri);
|
||||
@ -841,7 +844,7 @@ class Filters
|
||||
/**
|
||||
* Check the URI path as pseudo-regex
|
||||
*
|
||||
* @param string $uri URI path relative to baseURL (all lowercase)
|
||||
* @param string $uri URI path relative to baseURL (all lowercase, URL-decoded)
|
||||
* @param array $paths The except path patterns
|
||||
*/
|
||||
private function checkPseudoRegex(string $uri, array $paths): bool
|
||||
@ -854,7 +857,7 @@ class Filters
|
||||
$path = strtolower(str_replace('*', '.*', $path));
|
||||
|
||||
// Does this rule apply here?
|
||||
if (preg_match('#^' . $path . '$#', $uri, $match) === 1) {
|
||||
if (preg_match('#\A' . $path . '\z#u', $uri, $match) === 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
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,7 +13,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace CodeIgniter\Language;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IntlException;
|
||||
use MessageFormatter;
|
||||
|
||||
/**
|
||||
@ -195,9 +195,33 @@ class Language
|
||||
|
||||
$formatted = MessageFormatter::formatMessage($this->locale, $message, $args);
|
||||
if ($formatted === false) {
|
||||
throw new InvalidArgumentException(
|
||||
lang('Language.invalidMessageFormat', [$message, implode(',', $args)])
|
||||
// Format again to get the error message.
|
||||
try {
|
||||
$fmt = new MessageFormatter($this->locale, $message);
|
||||
$formatted = $fmt->format($args);
|
||||
$fmtError = '"' . $fmt->getErrorMessage() . '" (' . $fmt->getErrorCode() . ')';
|
||||
} catch (IntlException $e) {
|
||||
$fmtError = '"' . $e->getMessage() . '" (' . $e->getCode() . ')';
|
||||
}
|
||||
|
||||
$argsString = implode(
|
||||
', ',
|
||||
array_map(static fn ($element) => '"' . $element . '"', $args)
|
||||
);
|
||||
$argsUrlEncoded = implode(
|
||||
', ',
|
||||
array_map(static fn ($element) => '"' . rawurlencode($element) . '"', $args)
|
||||
);
|
||||
|
||||
log_message(
|
||||
'error',
|
||||
'Language.invalidMessageFormat: $message: "' . $message
|
||||
. '", $args: ' . $argsString
|
||||
. ' (urlencoded: ' . $argsUrlEncoded . '),'
|
||||
. ' MessageFormatter Error: ' . $fmtError
|
||||
);
|
||||
|
||||
return $message . "\n【Warning】Also, invalid string(s) was passed to the Language class. See log file for details.";
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
|
@ -15,6 +15,7 @@ namespace CodeIgniter\Router;
|
||||
|
||||
use Closure;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\Exceptions\BadRequestException;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\Method;
|
||||
use CodeIgniter\HTTP\Request;
|
||||
@ -130,11 +131,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
|
||||
@ -187,6 +200,8 @@ class Router implements RouterInterface
|
||||
// Decode URL-encoded string
|
||||
$uri = urldecode($uri);
|
||||
|
||||
$this->checkDisallowedChars($uri);
|
||||
|
||||
// Restart filterInfo
|
||||
$this->filtersInfo = [];
|
||||
|
||||
@ -424,7 +439,7 @@ class Router implements RouterInterface
|
||||
}, is_array($handler) ? key($handler) : $handler);
|
||||
|
||||
throw new RedirectException(
|
||||
preg_replace('#^' . $routeKey . '$#u', $redirectTo, $uri),
|
||||
preg_replace('#\A' . $routeKey . '\z#u', $redirectTo, $uri),
|
||||
$this->collection->getRedirectCode($routeKey)
|
||||
);
|
||||
}
|
||||
@ -484,7 +499,7 @@ class Router implements RouterInterface
|
||||
|
||||
if (config(Routing::class)->multipleSegmentsOneParam === false) {
|
||||
// Using back-references
|
||||
$segments = explode('/', preg_replace('#^' . $routeKey . '$#u', $handler, $uri));
|
||||
$segments = explode('/', preg_replace('#\A' . $routeKey . '\z#u', $handler, $uri));
|
||||
} else {
|
||||
if (str_contains($methodAndParams, '/')) {
|
||||
[$method, $handlerParams] = explode('/', $methodAndParams, 2);
|
||||
@ -708,4 +723,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 . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1058,6 +1058,52 @@ final class FiltersTest extends CIUnitTestCase
|
||||
$this->assertSame($expected, $filters->initialize($uri)->getFilters());
|
||||
}
|
||||
|
||||
public function testMatchesURIWithUnicode(): void
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
|
||||
$config = [
|
||||
'aliases' => [
|
||||
'foo' => '',
|
||||
'bar' => '',
|
||||
'frak' => '',
|
||||
'baz' => '',
|
||||
],
|
||||
'globals' => [
|
||||
'before' => [
|
||||
'foo' => ['except' => '日本語/*'],
|
||||
'bar',
|
||||
],
|
||||
'after' => [
|
||||
'foo' => ['except' => '日本語/*'],
|
||||
'baz',
|
||||
],
|
||||
],
|
||||
'filters' => [
|
||||
'frak' => [
|
||||
'before' => ['日本語/*'],
|
||||
'after' => ['日本語/*'],
|
||||
],
|
||||
],
|
||||
];
|
||||
$filtersConfig = $this->createConfigFromArray(FiltersConfig::class, $config);
|
||||
$filters = $this->createFilters($filtersConfig);
|
||||
|
||||
// URIs passed to Filters are URL-encoded.
|
||||
$uri = '%E6%97%A5%E6%9C%AC%E8%AA%9E/foo/bar';
|
||||
$expected = [
|
||||
'before' => [
|
||||
'bar',
|
||||
'frak',
|
||||
],
|
||||
'after' => [
|
||||
'baz',
|
||||
'frak',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expected, $filters->initialize($uri)->getFilters());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/codeigniter4/CodeIgniter4/issues/1907
|
||||
*/
|
||||
|
@ -475,8 +475,8 @@ final class URITest extends CIUnitTestCase
|
||||
{
|
||||
return [
|
||||
'dot-segment' => [
|
||||
'/./path/to/nowhere',
|
||||
'/path/to/nowhere',
|
||||
'/./path/to/nowhere', // path
|
||||
'/path/to/nowhere', // expectedPath
|
||||
],
|
||||
'double-dots' => [
|
||||
'/../path/to/nowhere',
|
||||
@ -486,18 +486,30 @@ final class URITest extends CIUnitTestCase
|
||||
'./path/to/nowhere',
|
||||
'/path/to/nowhere',
|
||||
],
|
||||
'start-double' => [
|
||||
'start-double-dot' => [
|
||||
'../path/to/nowhere',
|
||||
'/path/to/nowhere',
|
||||
],
|
||||
'decoded' => [
|
||||
'../%41path',
|
||||
'decode-percent-encoded-chars' => [
|
||||
'/%41path',
|
||||
'/Apath',
|
||||
],
|
||||
'encoded' => [
|
||||
'decode-slash' => [
|
||||
'/a%2Fb',
|
||||
'/a/b',
|
||||
],
|
||||
'encode-unreserved-chars' => [
|
||||
'/path^here',
|
||||
'/path%5Ehere',
|
||||
],
|
||||
'encode-multibyte-chars' => [
|
||||
'/あいう',
|
||||
'/%E3%81%82%E3%81%84%E3%81%86',
|
||||
],
|
||||
'encode-invalid-percent-encoding' => [
|
||||
'/pa%2-th',
|
||||
'/pa%252-th',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ namespace CodeIgniter\Language;
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use CodeIgniter\Test\Mock\MockLanguage;
|
||||
use Config\Services;
|
||||
use InvalidArgumentException;
|
||||
use MessageFormatter;
|
||||
use Tests\Support\Language\SecondMockLanguage;
|
||||
|
||||
@ -139,18 +138,14 @@ final class LanguageTest extends CIUnitTestCase
|
||||
$this->markTestSkipped('No intl support.');
|
||||
}
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid message format: "تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.", args: "password,hits,wording"'
|
||||
);
|
||||
|
||||
$this->lang->setLocale('ar');
|
||||
|
||||
$this->lang->setData('Auth', [
|
||||
'errorPasswordPwned' => 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.',
|
||||
]);
|
||||
$line = 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.';
|
||||
$this->lang->setData('Auth', ['errorPasswordPwned' => $line]);
|
||||
|
||||
$this->lang->getLine('Auth.errorPasswordPwned', ['password', 'hits', 'wording']);
|
||||
$output = $this->lang->getLine('Auth.errorPasswordPwned', ['password', 'hits', 'wording']);
|
||||
|
||||
$this->assertSame($line . "\n【Warning】Also, invalid string(s) was passed to the Language class. See log file for details.", $output);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,11 +16,13 @@ namespace CodeIgniter\Router;
|
||||
use CodeIgniter\Config\Factories;
|
||||
use CodeIgniter\Config\Services;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\Exceptions\BadRequestException;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\IncomingRequest;
|
||||
use CodeIgniter\HTTP\Method;
|
||||
use CodeIgniter\Router\Exceptions\RouterException;
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use Config\App;
|
||||
use Config\Modules;
|
||||
use Config\Routing;
|
||||
use Tests\Support\Filters\Customfilter;
|
||||
@ -96,6 +98,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);
|
||||
@ -817,6 +829,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);
|
||||
@ -836,6 +851,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');
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
Version 4.4.7
|
||||
#############
|
||||
|
||||
Release Date: Unreleased
|
||||
Release Date: March 29, 2024
|
||||
|
||||
**4.4.7 release of CodeIgniter4**
|
||||
|
||||
@ -10,6 +10,20 @@ Release Date: Unreleased
|
||||
:local:
|
||||
:depth: 3
|
||||
|
||||
********
|
||||
SECURITY
|
||||
********
|
||||
|
||||
- **Language:** *Language class DoS Vulnerability* was fixed.
|
||||
See the `Security advisory GHSA-39fp-mqmm-gxj6 <https://github.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-39fp-mqmm-gxj6>`_
|
||||
for more information.
|
||||
- **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.
|
||||
- **Filters:** A bug where URI paths processed by Filters were not URL-decoded
|
||||
has been fixed. See :ref:`upgrade-447-filter-paths` for details.
|
||||
|
||||
********
|
||||
BREAKING
|
||||
********
|
||||
@ -19,18 +33,6 @@ BREAKING
|
||||
hours due to Daylight Saving Time (DST). This bug has been fixed. See
|
||||
:ref:`Note in Times and Dates <time-viewing-differences>` for details.
|
||||
|
||||
***************
|
||||
Message Changes
|
||||
***************
|
||||
|
||||
*******
|
||||
Changes
|
||||
*******
|
||||
|
||||
************
|
||||
Deprecations
|
||||
************
|
||||
|
||||
**********
|
||||
Bugs Fixed
|
||||
**********
|
||||
|
@ -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
|
||||
|
@ -26,7 +26,7 @@ copyright = '2019-' + str(year_now) + ' CodeIgniter Foundation'
|
||||
version = '4.4'
|
||||
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '4.4.6'
|
||||
release = '4.4.7'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
|
@ -58,6 +58,52 @@ 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: `` ``
|
||||
|
||||
.. 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.
|
||||
|
||||
Adding Permitted Characters
|
||||
---------------------------
|
||||
|
||||
The permitted characters can be changed by ``Config\App::$permittedURIChars``.
|
||||
|
||||
If you want to use Unicode for URI paths, modify it to allow the characters to
|
||||
be used. For example, if you want to use Bengali, you will need to set the
|
||||
following value in **app/Config/App.php**::
|
||||
|
||||
public string $permittedURIChars = 'a-z 0-9~%.:_\-\x{0980}-\x{09ff}';
|
||||
|
||||
A full list of Unicode ranges can be found at Wikipedia's `Unicode block`_.
|
||||
|
||||
.. _Unicode block: https://en.wikipedia.org/wiki/Unicode_block
|
||||
|
||||
.. _urls-remove-index-php:
|
||||
|
||||
Removing the index.php file
|
||||
|
@ -163,6 +163,11 @@ an array with the ``except`` key and a URI path (relative to BaseURL) to match a
|
||||
|
||||
.. literalinclude:: filters/006.php
|
||||
|
||||
.. Warning:: Prior to v4.4.7, due to a bug, the URI paths processed by the filter
|
||||
were not URL-decoded. In other words, the URI paths specified in the routing
|
||||
and the URI paths specified in the filter could be different.
|
||||
See :ref:`upgrade-447-filter-paths` for details.
|
||||
|
||||
Any place you can use a URI path (relative to BaseURL) in the filter settings, you can use a regular expression or, like in this example, use
|
||||
an asterisk (``*``) for a wildcard that will match all characters after that. In this example, any URI path starting with ``api/``
|
||||
would be exempted from CSRF protection, but the site's forms would all be protected.
|
||||
@ -198,6 +203,11 @@ a list of URI path (relative to BaseURL) patterns that filter should apply to:
|
||||
|
||||
.. literalinclude:: filters/009.php
|
||||
|
||||
.. Warning:: Prior to v4.4.7, due to a bug, the URI paths processed by the filter
|
||||
were not URL-decoded. In other words, the URI paths specified in the routing
|
||||
and the URI paths specified in the filter could be different.
|
||||
See :ref:`upgrade-447-filter-paths` for details.
|
||||
|
||||
.. _filters-filters-filter-arguments:
|
||||
|
||||
Filter Arguments
|
||||
|
@ -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
|
||||
===========
|
||||
|
||||
@ -28,6 +40,40 @@ The error page has been updated. Please update the following files:
|
||||
Breaking Changes
|
||||
****************
|
||||
|
||||
.. _upgrade-447-filter-paths:
|
||||
|
||||
Paths in Controller Filters
|
||||
===========================
|
||||
|
||||
A bug where URI paths processed by :doc:`../incoming/filters` were not URL-decoded has been fixed.
|
||||
|
||||
.. note:: Note that :doc:`Router <../incoming/routing>` processes URL-decoded URI paths.
|
||||
|
||||
``Config\Filters`` has some places to specify the URI paths. If the paths have
|
||||
different values when URL-decoded, change them to the URL-decoded values.
|
||||
|
||||
E.g.,:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public array $globals = [
|
||||
'before' => [
|
||||
'csrf' => ['except' => '%E6%97%A5%E6%9C%AC%E8%AA%9E/*'],
|
||||
],
|
||||
// ...
|
||||
];
|
||||
|
||||
↓
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public array $globals = [
|
||||
'before' => [
|
||||
'csrf' => ['except' => '日本語/*'],
|
||||
],
|
||||
// ...
|
||||
];
|
||||
|
||||
Time::difference() and DST
|
||||
==========================
|
||||
|
||||
@ -43,10 +89,6 @@ In the unlikely event that you wish to maintain the behavior of the previous
|
||||
versions, change the time zone of both dates being compared to UTC before passing
|
||||
them to ``Time::difference()``.
|
||||
|
||||
*********************
|
||||
Breaking Enhancements
|
||||
*********************
|
||||
|
||||
*************
|
||||
Project Files
|
||||
*************
|
||||
@ -66,7 +108,9 @@ and it is recommended that you merge the updated versions with your application:
|
||||
Config
|
||||
------
|
||||
|
||||
- @TODO
|
||||
- app/Config/App.php
|
||||
- The property ``$permittedURIChars`` was added. See :ref:`urls-uri-security`
|
||||
for details.
|
||||
|
||||
All Changes
|
||||
===========
|
||||
@ -74,4 +118,19 @@ All Changes
|
||||
This is a list of all files in the **project space** that received changes;
|
||||
many will be simple comments or formatting that have no effect on the runtime:
|
||||
|
||||
- @TODO
|
||||
- app/Config/Cache.php
|
||||
- app/Config/ContentSecurityPolicy.php
|
||||
- app/Config/Database.php
|
||||
- app/Config/Exceptions.php
|
||||
- app/Config/Filters.php
|
||||
- app/Config/Format.php
|
||||
- app/Config/Logger.php
|
||||
- app/Config/Mimes.php
|
||||
- app/Config/Routing.php
|
||||
- app/Config/Toolbar.php
|
||||
- app/Config/Validation.php
|
||||
- app/Config/View.php
|
||||
- app/Controllers/BaseController.php
|
||||
- app/Views/errors/html/debug.css
|
||||
- app/Views/errors/html/error_exception.php
|
||||
- composer.json
|
||||
|
Loading…
x
Reference in New Issue
Block a user