From 2dce1ffda218456e19f28edce8b0d74122f4d55c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 20:49:04 +0300 Subject: Fix #1268 (or rather enforce some security measures, there's nothing really broken) --- system/core/Lang.php | 14 +++++++------- user_guide_src/source/changelog.rst | 1 + user_guide_src/source/libraries/language.rst | 7 ++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/system/core/Lang.php b/system/core/Lang.php index 3001f1b13..601348aa4 100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -65,11 +65,11 @@ class CI_Lang { /** * Load a language file * - * @param mixed the name of the language file to be loaded - * @param string the language (english, etc.) - * @param bool return loaded array of translations - * @param bool add suffix to $langfile - * @param string alternative path to look for language file + * @param mixed $langile the name of the language file to be loaded + * @param string $idiom = '' the language (english, etc.) + * @param bool $return = FALSE return loaded array of translations + * @param bool $add_suffix = TRUE add suffix to $langfile + * @param string $alt_path = '' alternative path to look for language file * @return mixed */ public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') @@ -83,10 +83,10 @@ class CI_Lang { $langfile .= '.php'; - if ($idiom === '') + if (empty($idiom) OR ! ctype_alpha($idiom)) { $config =& get_config(); - $idiom = ( ! empty($config['language'])) ? $config['language'] : 'english'; + $idiom = empty($config['language']) ? 'english' : $config['language']; } if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom) diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index de5ec4758..92f6a03ef 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -219,6 +219,7 @@ Release Date: Not Released - :doc:`Encryption Library ` changes include: - Added support for hashing algorithms other than SHA1 and MD5. - Removed previously deprecated ``sha1()`` method. + - Changed :doc:`Language Library ` method ``load()`` to filter the language name with ``ctype_digit()``. - Core diff --git a/user_guide_src/source/libraries/language.rst b/user_guide_src/source/libraries/language.rst index ec678cd21..b231f14a3 100644 --- a/user_guide_src/source/libraries/language.rst +++ b/user_guide_src/source/libraries/language.rst @@ -54,7 +54,9 @@ first. Loading a language file is done with the following code:: Where filename is the name of the file you wish to load (without the file extension), and language is the language set containing it (ie, english). If the second parameter is missing, the default language set -in your application/config/config.php file will be used. +in your *application/config/config.php* file will be used. + +.. note:: The *language* parameter can only consist of letters. Fetching a Line of Text ======================= @@ -67,8 +69,7 @@ text using this function:: Where language_key is the array key corresponding to the line you wish to show. -Note: This function simply returns the line. It does not echo it for -you. +.. note:: This method simply returns the line. It does not echo it. Using language lines as form labels ----------------------------------- -- cgit v1.2.3-24-g4f1b From f795ab52dadaef20afd3a97ad4c8ed408e211dc2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 21:28:25 +0300 Subject: [ci skip] Document get_csrf_token_name(), get_csrf_hash() (issue #715) --- system/core/Security.php | 2 +- user_guide_src/source/libraries/security.rst | 45 +++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/system/core/Security.php b/system/core/Security.php index 2fbc5b34c..d7c82712d 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -161,7 +161,7 @@ class CI_Security { } // Do the tokens exist in both the _POST and _COOKIE arrays? - if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name]) + if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? { $this->csrf_show_error(); diff --git a/user_guide_src/source/libraries/security.rst b/user_guide_src/source/libraries/security.rst index e7d25555f..05553142f 100644 --- a/user_guide_src/source/libraries/security.rst +++ b/user_guide_src/source/libraries/security.rst @@ -26,7 +26,7 @@ processing since it requires a fair amount of processing overhead. To filter data through the XSS filter use this function: $this->security->xss_clean() -============================= +============================ Here is an usage example:: @@ -56,7 +56,7 @@ browser may attempt to execute. } $this->security->sanitize_filename() -===================================== +==================================== When accepting filenames from user input, it is best to sanitize them to prevent directory traversal and other security related issues. To do so, @@ -76,16 +76,35 @@ parameter, $relative_path to TRUE. Cross-site request forgery (CSRF) ================================= -You can enable csrf protection by opening your +You can enable CSRF protection by opening your application/config/config.php file and setting this:: $config['csrf_protection'] = TRUE; -If you use the :doc:`form helper <../helpers/form_helper>` the -form_open() function will automatically insert a hidden csrf field in -your forms. +If you use the :doc:`form helper <../helpers/form_helper>`, then +``form_open()`` will automatically insert a hidden csrf field in +your forms. If not, then you can use ``csrf_get_token_name()`` +and ``csrf_get_hash()`` -Tokens may be either regenerated on every submission (default) or kept the same throughout the life of the CSRF cookie. The default regeneration of tokens provides stricter security but may result in usability concerns as other tokens become invalid (back/forward navigation, multiple tabs/windows, asynchronous actions, etc). You may alter this behavior by editing the following config parameter:: +:: + + $csrf = array( + 'name' => $this->security->csrf_get_token_name(), + 'hash' => $this->security->csrf_get_hash() + ); + + ... + + + +Tokens may be either regenerated on every submission (default) or +kept the same throughout the life of the CSRF cookie. The default +regeneration of tokens provides stricter security, but may result +in usability concerns as other tokens become invalid (back/forward +navigation, multiple tabs/windows, asynchronous actions, etc). You +may alter this behavior by editing the following config parameter + +:: $config['csrf_regeneration'] = TRUE; @@ -95,3 +114,15 @@ by editing the 'csrf_exclude_uris' config parameter:: $config['csrf_exclude_uris'] = array('api/person/add'); +$this->security->get_csrf_token_name() +====================================== + +Returns the CSRF token name, which is set by +``$config['csrf_token_name']``. + +$this->security->get_csrf_hash() +================================ + +Returns the CSRF hash value. Useful in combination with +``get_csrf_token_name()`` for manually building forms or +sending valid AJAX POST requests. \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 9d0ab04e1e39bc93c59f60844dd2cf9176443028 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 21:47:39 +0300 Subject: Fix #191 --- system/core/Loader.php | 8 ++++---- user_guide_src/source/changelog.rst | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/system/core/Loader.php b/system/core/Loader.php index 5de2e5dde..b316c8e1b 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -318,9 +318,9 @@ class CI_Loader { /** * Database Loader * - * @param string the DB credentials - * @param bool whether to return the DB object - * @param bool whether to enable query builder (this allows us to override the config setting) + * @param mixed $params = '' the DB settings + * @param bool $return = FALSE whether to return the DB object + * @param bool $query_builder = NULL whether to enable query builder (overrides the config setting) * @return object */ public function database($params = '', $return = FALSE, $query_builder = NULL) @@ -329,7 +329,7 @@ class CI_Loader { $CI =& get_instance(); // Do we even need to load the database class? - if (class_exists('CI_DB') && $return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db)) + if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)) { return FALSE; } diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 92f6a03ef..ca46e9db1 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -377,6 +377,7 @@ Bug fixes for 3.0 - Fixed a bug (#1766) - :doc:`Query Builder ` didn't always take into account the *dbprefix* setting. - Fixed a bug (#779) - :doc:`URI Class ` didn't always trim slashes from the *uri_string* as shown in the documentation. - Fixed a bug (#134) - :doc:`Database Caching ` method ``delete_cache()`` didn't work in some cases due to *cachedir* not being initialized properly. +- Fixed a bug (#191) - :doc:`Loader Library ` ignored attempts for (re)loading databases to ``get_instance()->db`` even when the old database connection is dead. Version 2.1.3 ============= -- cgit v1.2.3-24-g4f1b From a0836b9293a50905651e1a2ed624f3e331be765f Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 22:03:42 +0300 Subject: Fix #1255 --- system/libraries/User_agent.php | 8 +++++++- user_guide_src/source/changelog.rst | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index ff596f04b..3387d4aa6 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -466,7 +466,13 @@ class CI_User_agent { */ public function is_referral() { - return ! empty($_SERVER['HTTP_REFERER']); + if (empty($_SERVER['HTTP_REFERER'])) + { + return FALSE; + } + + $referer = parse_url($_SERVER['HTTP_REFERER']); + return ! (empty($referer['host']) && strpos(config_item('base_url'), $referer['host']) !== FALSE); } // -------------------------------------------------------------------- diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index ca46e9db1..afe2a6862 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -378,6 +378,7 @@ Bug fixes for 3.0 - Fixed a bug (#779) - :doc:`URI Class ` didn't always trim slashes from the *uri_string* as shown in the documentation. - Fixed a bug (#134) - :doc:`Database Caching ` method ``delete_cache()`` didn't work in some cases due to *cachedir* not being initialized properly. - Fixed a bug (#191) - :doc:`Loader Library ` ignored attempts for (re)loading databases to ``get_instance()->db`` even when the old database connection is dead. +- Fixed a bug (#1255) - :doc:`User Agent Library ` method ``is_referral()`` only checked if ``$_SERVER['HTTP_REFERER']`` exists. Version 2.1.3 ============= -- cgit v1.2.3-24-g4f1b From d87f6bf028e4ab5cd787c8915ea39c3946e338ae Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 22:12:53 +0300 Subject: Fix #1146 --- system/helpers/download_helper.php | 9 +++------ user_guide_src/source/changelog.rst | 1 + 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index 0232adfe4..2c26a36d5 100644 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -110,14 +110,11 @@ if ( ! function_exists('force_download')) // Internet Explorer-specific headers if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) { - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - } - else - { - header('Pragma: no-cache'); + header('Cache-Control: no-cache, no-store, must-revalidate'); } + header('Pragma: no-cache'); + exit($data); } } diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index afe2a6862..8576dbf19 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -379,6 +379,7 @@ Bug fixes for 3.0 - Fixed a bug (#134) - :doc:`Database Caching ` method ``delete_cache()`` didn't work in some cases due to *cachedir* not being initialized properly. - Fixed a bug (#191) - :doc:`Loader Library ` ignored attempts for (re)loading databases to ``get_instance()->db`` even when the old database connection is dead. - Fixed a bug (#1255) - :doc:`User Agent Library ` method ``is_referral()`` only checked if ``$_SERVER['HTTP_REFERER']`` exists. +- Fixed a bug (#1146) - :doc:`Download Helper ` function ``force_download()`` incorrectly sent *Cache-Control* directives *pre-check* and *post-check* to Internet Explorer. Version 2.1.3 ============= -- cgit v1.2.3-24-g4f1b From 04c50f50ad1f522f9521197f9ee7059da52168e0 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 23:05:25 +0300 Subject: [ci skip] Document Query Builder method replace() (fix #1651) --- user_guide_src/source/database/query_builder.rst | 31 +++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index 6ca72914f..5380d0998 100644 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -681,6 +681,35 @@ associative array of values. .. note:: All values are escaped automatically producing safer queries. +$this->db->replace() +==================== + +This method executes a REPLACE statement, which is basically the SQL +standard for (optional) DELETE + INSERT, using *PRIMARY* and *UNIQUE* +keys as the determining factor. +In our case, it will save you from the need to implement complex +logics with different combinations of ``select()``, ``update()``, +``delete()`` and ``insert()`` calls. + +Example:: + + $data = array( + 'title' => 'My title', + 'name' => 'My Name', + 'date' => 'My date' + ); + + $this->db->replace('table', $data); + + // Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') + +In the above example, if we assume that the *title* field is our primary +key, then if a row containing 'My title' as the *title* value, that row +will be deleted with our new row data replacing it. + +Usage of the ``set()`` method is also allowed and all fields are +automatically escaped, just like with ``insert()``. + $this->db->set() ================ @@ -740,7 +769,6 @@ Or an object:: $this->db->set($object); $this->db->insert('mytable'); - ************* Updating Data ************* @@ -792,6 +820,7 @@ Or as an array:: You may also use the $this->db->set() function described above when performing updates. + $this->db->update_batch() ========================= -- cgit v1.2.3-24-g4f1b From 4a7cc768a836a12c4839e482715b3859e0c16d7d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 23:52:05 +0300 Subject: Fix #1811 --- system/core/URI.php | 14 ++++++++------ user_guide_src/source/changelog.rst | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/system/core/URI.php b/system/core/URI.php index 15e6a5599..40eaaeb6b 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -433,9 +433,9 @@ class CI_URI { /** * Generate a key value pair from the URI string or Re-routed URI string * - * @param int the starting segment number - * @param array an array of default values - * @param string which array we should use + * @param int $n = 3 the starting segment number + * @param array $default = array() an array of default values + * @param string $which = 'segment' which array we should use * @return array */ protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment') @@ -445,9 +445,11 @@ class CI_URI { return $default; } - if (isset($this->keyval[$n])) + in_array($which, array('segment', 'rsegment'), TRUE) OR $which = 'segment'; + + if (isset($this->keyval[$which], $this->keyval[$which][$n])) { - return $this->keyval[$n]; + return $this->keyval[$which][$n]; } if ($which === 'segment') @@ -499,7 +501,7 @@ class CI_URI { } // Cache the array for reuse - $this->keyval[$n] = $retval; + $this->keyval[$which][$n] = $retval; return $retval; } diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 8576dbf19..d3cebc7cc 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -380,6 +380,7 @@ Bug fixes for 3.0 - Fixed a bug (#191) - :doc:`Loader Library ` ignored attempts for (re)loading databases to ``get_instance()->db`` even when the old database connection is dead. - Fixed a bug (#1255) - :doc:`User Agent Library ` method ``is_referral()`` only checked if ``$_SERVER['HTTP_REFERER']`` exists. - Fixed a bug (#1146) - :doc:`Download Helper ` function ``force_download()`` incorrectly sent *Cache-Control* directives *pre-check* and *post-check* to Internet Explorer. +- Fixed a bug (#1811) - :doc:`URI Library ` didn't properly cache segments for ``uri_to_assoc()`` and ``ruri_to_assoc()``. Version 2.1.3 ============= -- cgit v1.2.3-24-g4f1b From 9093042c1f56bbdce2785ec5de0cd4180b4e6216 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Oct 2012 23:53:12 +0300 Subject: Improve fix for #1811 --- system/core/URI.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/core/URI.php b/system/core/URI.php index 40eaaeb6b..72f293c18 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -501,6 +501,7 @@ class CI_URI { } // Cache the array for reuse + isset($this->keyval[$which]) OR $this->keyval[$which] = array(); $this->keyval[$which][$n] = $retval; return $retval; } -- cgit v1.2.3-24-g4f1b From e47425844e84d54c659280c04f450a3526b4e09d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 25 Oct 2012 13:25:13 +0300 Subject: Add missing delimiter in preg_quote() occurences (fix #1929) --- system/database/DB_driver.php | 10 +++++----- system/database/DB_query_builder.php | 2 +- system/helpers/url_helper.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 7f1434fc1..e8286aaa1 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -640,7 +640,7 @@ abstract class CI_DB_driver { // Make sure not to replace a chunk inside a string that happens to match the bind marker if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) { - $c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', + $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', str_replace($matches[0], str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), $sql, $c), @@ -652,7 +652,7 @@ abstract class CI_DB_driver { return $sql; } } - elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) + elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) { return $sql; } @@ -1007,13 +1007,13 @@ abstract class CI_DB_driver { if (is_array($this->_escape_char)) { $preg_ec = array( - preg_quote($this->_escape_char[0]), preg_quote($this->_escape_char[1]), + preg_quote($this->_escape_char[0], '/'), preg_quote($this->_escape_char[1], '/'), $this->_escape_char[0], $this->_escape_char[1] ); } else { - $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char); + $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/'); $preg_ec[2] = $preg_ec[3] = $this->_escape_char; } } @@ -1172,7 +1172,7 @@ abstract class CI_DB_driver { if (empty($_operators)) { $_les = ($this->_like_escape_str !== '') - ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr))) + ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/') : ''; $_operators = array( '\s*(?:<|>|!)?=\s*', // =, <=, >=, != diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index 5ea9643fe..ed00510ac 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -2077,7 +2077,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++) { if (($op = $this->_get_operator($conditions[$ci])) === FALSE - OR ! preg_match('/^(\(?)(.*)('.preg_quote($op).')\s*(.*(? '', -- cgit v1.2.3-24-g4f1b