summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/core/Security.php12
-rw-r--r--system/database/DB_query_builder.php51
-rw-r--r--system/database/drivers/oci8/oci8_driver.php15
-rw-r--r--system/database/drivers/postgre/postgre_driver.php7
-rw-r--r--system/libraries/Email.php6
-rw-r--r--system/libraries/Xmlrpc.php2
-rw-r--r--user_guide_src/source/changelog.rst24
-rw-r--r--user_guide_src/source/helpers/string_helper.rst2
-rw-r--r--user_guide_src/source/helpers/url_helper.rst4
-rw-r--r--user_guide_src/source/installation/downloads.rst3
-rw-r--r--user_guide_src/source/installation/upgrade_319.rst14
-rw-r--r--user_guide_src/source/installation/upgrading.rst1
12 files changed, 102 insertions, 39 deletions
diff --git a/system/core/Security.php b/system/core/Security.php
index 091093637..b19a6fb02 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -545,6 +545,14 @@ class CI_Security {
$str
);
+ // Same thing, but for "tag functions" (e.g. eval`some code`)
+ // See https://github.com/bcit-ci/CodeIgniter/issues/5420
+ $str = preg_replace(
+ '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)`(.*?)`#si',
+ '\\1\\2`\\3`',
+ $str
+ );
+
// Final clean up
// This adds a bit of extra precaution in case
// something got through the above filters
@@ -907,7 +915,7 @@ class CI_Security {
return str_replace(
$match[1],
preg_replace(
- '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|d\s*a\s*t\s*a\s*:)#si',
+ '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|d\s*a\s*t\s*a\s*:)#si',
'',
$this->_filter_attributes($match[1])
),
@@ -935,7 +943,7 @@ class CI_Security {
return str_replace(
$match[1],
preg_replace(
- '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|base64\s*,)#si',
+ '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes($match[1])
),
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index d271964b9..744c4970e 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -673,7 +673,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
if ($escape === TRUE)
{
- $v = ' '.$this->escape($v);
+ $v = $this->escape($v);
}
if ( ! $this->_has_operator($k))
@@ -691,10 +691,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
}
- $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
+ ${$qb_key} = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape);
+ $this->{$qb_key}[] = ${$qb_key};
if ($this->qb_caching === TRUE)
{
- $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
+ $this->{$qb_cache_key}[] = ${$qb_key};
$this->qb_cache_exists[] = substr($qb_key, 3);
}
@@ -906,6 +907,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$wh_in = array(
'condition' => $prefix.$key.$not.' IN('.implode(', ', $wh_in).')',
+ 'value' => NULL,
'escape' => $escape
);
@@ -1034,33 +1036,34 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$v = $this->escape_like_str($v);
}
- if ($side === 'none')
+ switch ($side)
{
- $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'";
- }
- elseif ($side === 'before')
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'";
- }
- elseif ($side === 'after')
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'";
- }
- else
- {
- $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'";
+ case 'none':
+ $v = "'{$v}'";
+ break;
+ case 'before':
+ $v = "%'{$v}'";
+ break;
+ case 'after':
+ $v = "'{$v}%'";
+ break;
+ case 'both':
+ default:
+ $v = "'%{$v}%'";
+ break;
}
// some platforms require an escape sequence definition for LIKE wildcards
if ($escape === TRUE && $this->_like_escape_str !== '')
{
- $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr);
+ $v .= sprintf($this->_like_escape_str, $this->_like_escape_chr);
}
- $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape);
+ $qb_where = array('condition' => "{$prefix} {$k} {$not} LIKE", 'value' => $v, 'escape' => $escape);
+ $this->qb_where[] = $qb_where;
if ($this->qb_caching === TRUE)
{
- $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape);
+ $this->qb_cache_where[] = $qb_where;
$this->qb_cache_exists[] = 'where';
}
}
@@ -1085,6 +1088,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
$where = array(
'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (',
+ 'value' => NULL,
'escape' => FALSE
);
@@ -1145,6 +1149,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->qb_where_group_started = FALSE;
$where = array(
'condition' => str_repeat(' ', $this->qb_where_group_count--).')',
+ 'value' => NULL,
'escape' => FALSE
);
@@ -1505,7 +1510,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// --------------------------------------------------------------------
/**
- * Get_Where
+ * get_where()
*
* Allows the where clause, limit and offset to be added directly
*
@@ -2467,7 +2472,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
elseif ($this->{$qb_key}[$i]['escape'] === FALSE)
{
- $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'];
+ $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'].(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : '');
continue;
}
@@ -2506,7 +2511,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
.' '.trim($matches[3]).$matches[4].$matches[5];
}
- $this->{$qb_key}[$i] = implode('', $conditions);
+ $this->{$qb_key}[$i] = implode('', $conditions).(isset($this->{$qb_key}[$i]['value']) ? ' '.$this->{$qb_key}[$i]['value'] : '');
}
return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ")
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 1bd977390..b90db4bd2 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -97,7 +97,7 @@ class CI_DB_oci8_driver extends CI_DB {
*
* @var bool
*/
- public $limit_used;
+ public $limit_used = FALSE;
// --------------------------------------------------------------------
@@ -685,4 +685,17 @@ class CI_DB_oci8_driver extends CI_DB {
oci_close($this->conn_id);
}
+ // --------------------------------------------------------------------
+
+ /**
+ * We need to reset our $limit_used hack flag, so it doesn't propagate
+ * to subsequent queries.
+ *
+ * @return void
+ */
+ protected function _reset_select()
+ {
+ $this->limit_used = FALSE;
+ parent::_reset_select();
+ }
}
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index cae162e2e..e9b1e991c 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -218,8 +218,8 @@ class CI_DB_postgre_driver extends CI_DB {
* and so we'll have to fall back to running a query in
* order to get it.
*/
- return isset($pg_version['server'])
- ? $this->data_cache['version'] = $pg_version['server']
+ return (isset($pg_version['server']) && preg_match('#^(\d+\.\d+)#', $pg_version['server'], $match))
+ ? $this->data_cache['version'] = $match[1]
: parent::version();
}
@@ -348,8 +348,7 @@ class CI_DB_postgre_driver extends CI_DB {
*/
public function insert_id()
{
- $v = pg_version($this->conn_id);
- $v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4
+ $v = $this->version();
$table = (func_num_args() > 0) ? func_get_arg(0) : NULL;
$column = (func_num_args() > 1) ? func_get_arg(1) : NULL;
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 1847cc96f..beb2ffa17 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1824,7 +1824,11 @@ class CI_Email {
{
if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@'))
{
- $email = self::substr($email, 0, ++$atpos).idn_to_ascii(self::substr($email, $atpos), 0, INTL_IDNA_VARIANT_UTS46);
+ list($account, $domain) = explode('@', $email, 2);
+ $domain = defined('INTL_IDNA_VARIANT_UTS46')
+ ? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46)
+ : idn_to_ascii($domain);
+ $email = $account.'@'.$domain;
}
return (filter_var($email, FILTER_VALIDATE_EMAIL) === $email && preg_match('#\A[a-z0-9._+-]+@[a-z0-9.-]{1,253}\z#i', $email));
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 1d33b7742..8cc1c83f5 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -1179,7 +1179,7 @@ class XML_RPC_Message extends CI_Xmlrpc
$data = implode("\r\n", $lines);
// Parse XML data
- if ( ! xml_parse($parser, $data, count($data)))
+ if ( ! xml_parse($parser, $data, TRUE))
{
$errstr = sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($parser)),
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 8aede9406..b42b21722 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -128,19 +128,37 @@ Release Date: Not Released
- Updated to always create PNG images instead of JPEG.
-Version 3.1.8
+Version 3.1.9
=============
Release Date: Not Released
+
+Version 3.1.8
+=============
+
+Release Date: Mar 22, 2018
+
+- **Security**
+
+ - Updated :doc:`URL Helper <helpers/url_helper>` function :php:func:`auto_link()` to add ``rel="noopener"`` to generated links in order to prevent tab hijacking.
+ - Updated :doc:`Security Library <libraries/security>` method ``xss_clean()`` to also filter JavaScript tag functions.
+ - Fixed a bug where :doc:`Security Library <libraries/security>` method ``xss_clean()`` didn't check for parentheses around JavaScript's ``document``.
+
- General Changes
- Updated :doc:`Email Library <libraries/email>` to always negotiate between TLS 1.0, 1.1, 1.2 when possible (PHP 5.6+) for SMTP connections.
+ - Updated :doc:`Database Library <database/index>` method ``version()`` to exclude suffixes to the main version numbers with the 'postgre' driver.
Bug fixes for 3.1.8
-------------------
- Fixed a bug where :doc:`Form Validation Library <libraries/form_validation>`, :doc:`Email Library <libraries/email>` tried to use ``INTL_IDNA_VARIANT_UTS46`` when it was undeclared.
+- Fixed a bug where :doc:`Query Builder <database/query_builder>` methods ``where()``, ``having()`` treated values passed to them as arbitrary SQL.
+- Fixed a bug (#5423) - :doc:`Database Library <database/index>` method ``insert_id()`` failed due to incorrect server version parsing with the 'postgre' driver.
+- Fixed a bug (#5425) - :doc:`XML-RPC Library <libraries/xmlrpc>` produced an error message related to ``count()`` on PHP 7.2.
+- Fixed a bug (#5434) - :doc:`Image Manipulation Library <libraries/image_lib>` attempted to ``chmod()`` while rendering images with the ``dynamic_output`` option.
+- Fixed a bug (#5435) - :doc:`Database Results <database/results>` method ``field_data()`` hid info about one field if ``limit()`` was previously used with the 'oci8' driver.
Version 3.1.7
=============
@@ -2057,7 +2075,7 @@ Hg Tag: v2.0.0
precision.
- Added alpha, and sha1 string types to random_string() in the
:doc:`String Helper <helpers/string_helper>`.
- - Modified prep_url() so as to not prepend http&#58;// if the supplied
+ - Modified prep_url() so as to not prepend \http:// if the supplied
string already has a scheme.
- Modified get_file_info in the file helper, changing filectime()
to filemtime() for dates.
@@ -2797,7 +2815,7 @@ Bugfixes for 1.6.2
instantiating new Language and Exception objects, and not using the
error heading.
- Fixed a bug (#4413) where a URI containing slashes only e.g.
- 'http&#58;//example.com/index.php?//' would result in PHP errors
+ '\http://example.com/index.php?//' would result in PHP errors
- Fixed an array to string conversion error in the Validation library
(#4425)
- Fixed bug (#4451, #4299, #4339) where failed transactions will not
diff --git a/user_guide_src/source/helpers/string_helper.rst b/user_guide_src/source/helpers/string_helper.rst
index 7a45dc95b..4663bb08b 100644
--- a/user_guide_src/source/helpers/string_helper.rst
+++ b/user_guide_src/source/helpers/string_helper.rst
@@ -108,7 +108,7 @@ The following functions are available:
:rtype: string
Converts double slashes in a string to a single slash, except those
- found in URL protocol prefixes (e.g. http&#58;//).
+ found in URL protocol prefixes (e.g. \http://).
Example::
diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst
index 435a21df4..e117d37c0 100644
--- a/user_guide_src/source/helpers/url_helper.rst
+++ b/user_guide_src/source/helpers/url_helper.rst
@@ -144,7 +144,7 @@ The following functions are available:
be a string or an array.
.. note:: If you are building links that are internal to your application
- do not include the base URL (http&#58;//...). This will be added
+ do not include the base URL (\http://...). This will be added
automatically from the information specified in your config file.
Include only the URI segments you wish appended to the URL.
@@ -317,7 +317,7 @@ The following functions are available:
:returns: Protocol-prefixed URL string
:rtype: string
- This function will add http&#58;// in the event that a protocol prefix
+ This function will add \http:// in the event that a protocol prefix
is missing from a URL.
Pass the URL string to the function like this::
diff --git a/user_guide_src/source/installation/downloads.rst b/user_guide_src/source/installation/downloads.rst
index 0cf8e9fa3..f32d978f1 100644
--- a/user_guide_src/source/installation/downloads.rst
+++ b/user_guide_src/source/installation/downloads.rst
@@ -3,7 +3,8 @@ Downloading CodeIgniter
#######################
- `CodeIgniter v3.2.0-dev (Current version) <https://codeload.github.com/bcit-ci/CodeIgniter/zip/develop>`_
-- `CodeIgniter v3.1.8-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_
+- `CodeIgniter v3.1.9-dev <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1-stable>`_
+- `CodeIgniter v3.1.8 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.8>`_
- `CodeIgniter v3.1.7 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.7>`_
- `CodeIgniter v3.1.6 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.6>`_
- `CodeIgniter v3.1.5 <https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.5>`_
diff --git a/user_guide_src/source/installation/upgrade_319.rst b/user_guide_src/source/installation/upgrade_319.rst
new file mode 100644
index 000000000..99a7347a0
--- /dev/null
+++ b/user_guide_src/source/installation/upgrade_319.rst
@@ -0,0 +1,14 @@
+#############################
+Upgrading from 3.1.8 to 3.1.9
+#############################
+
+Before performing an update you should take your site offline by
+replacing the index.php file with a static one.
+
+Step 1: Update your CodeIgniter files
+=====================================
+
+Replace all files and directories in your *system/* directory.
+
+.. note:: If you have any custom developed files in these directories,
+ please make copies of them first.
diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst
index d523b66ec..32617389d 100644
--- a/user_guide_src/source/installation/upgrading.rst
+++ b/user_guide_src/source/installation/upgrading.rst
@@ -9,6 +9,7 @@ upgrading from.
:titlesonly:
Upgrading from 3.1.3+ to 3.2.x <upgrade_320>
+ Upgrading from 3.1.8 to 3.1.9 <upgrade_319>
Upgrading from 3.1.7 to 3.1.8 <upgrade_318>
Upgrading from 3.1.6 to 3.1.7 <upgrade_317>
Upgrading from 3.1.5 to 3.1.6 <upgrade_316>