From eea02de557834006c5d6a0bfccca7f39e75bf3a8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 27 Sep 2016 14:59:37 +0300 Subject: Fix entity_decode() issue --- system/core/Security.php | 39 ++++++++++++++++++-------------- tests/codeigniter/core/Security_test.php | 6 +++++ user_guide_src/source/changelog.rst | 4 ++++ 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/system/core/Security.php b/system/core/Security.php index 3a5da4fde..4a69daa18 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -669,6 +669,22 @@ class CI_Security { ? ENT_COMPAT | ENT_HTML5 : ENT_COMPAT; + if ( ! isset($_entities)) + { + $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset)); + + // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 + // entities to the array manually + if ($flag === ENT_COMPAT) + { + $_entities[':'] = ':'; + $_entities['('] = '('; + $_entities[')'] = ')'; + $_entities["\n"] = ' '; + $_entities["\t"] = ' '; + } + } + do { $str_compare = $str; @@ -676,22 +692,6 @@ class CI_Security { // Decode standard entities, avoiding false positives if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) { - if ( ! isset($_entities)) - { - $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset)); - - // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 - // entities to the array manually - if ($flag === ENT_COMPAT) - { - $_entities[':'] = ':'; - $_entities['('] = '('; - $_entities[')'] = ')'; - $_entities["\n"] = '&newline;'; - $_entities["\t"] = '&tab;'; - } - } - $replace = array(); $matches = array_unique(array_map('strtolower', $matches[0])); foreach ($matches as &$match) @@ -702,7 +702,7 @@ class CI_Security { } } - $str = str_ireplace(array_keys($replace), array_values($replace), $str); + $str = str_replace(array_keys($replace), array_values($replace), $str); } // Decode numeric & UTF16 two byte entities @@ -711,6 +711,11 @@ class CI_Security { $flag, $charset ); + + if ($flag === ENT_COMPAT) + { + $str = str_replace(array_values($_entities), array_keys($_entities), $str); + } } while ($str_compare !== $str); return $str; diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php index 8328c37cb..cbf0285ec 100644 --- a/tests/codeigniter/core/Security_test.php +++ b/tests/codeigniter/core/Security_test.php @@ -270,6 +270,12 @@ class Security_test extends CI_TestCase { $this->assertEquals('
Hello Booya
', $decoded); + $this->assertEquals('colon:', $this->security->entity_decode('colon:')); + $this->assertEquals("NewLine\n", $this->security->entity_decode('NewLine ')); + $this->assertEquals("Tab\t", $this->security->entity_decode('Tab ')); + $this->assertEquals("lpar(", $this->security->entity_decode('lpar(')); + $this->assertEquals("rpar)", $this->security->entity_decode('rpar)')); + // Issue #3057 (https://github.com/bcit-ci/CodeIgniter/issues/3057) $this->assertEquals( '&foo should not include a semicolon', diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index d41e79945..a0ed34a2f 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -7,6 +7,10 @@ Version 3.1.1 Release Date: Not Released +- **Security** + + - Fixed a flaw in :doc:`Security Library ` method ``entity_decode()`` (used by ``xss_clean()``) that affects HTML 5 entities when using PHP 5.3. + - General Changes - Added ``E_PARSE`` to the list of error levels detected by the shutdown handler. -- cgit v1.2.3-24-g4f1b