summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/core/Common.php47
-rw-r--r--system/core/Loader.php4
-rw-r--r--system/libraries/Email.php11
-rw-r--r--system/libraries/Image_lib.php14
-rw-r--r--system/libraries/Upload.php6
-rw-r--r--user_guide_src/source/changelog.rst2
-rw-r--r--user_guide_src/source/general/common_functions.rst15
7 files changed, 87 insertions, 12 deletions
diff --git a/system/core/Common.php b/system/core/Common.php
index 3b7ea6ad4..aea5f1808 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -651,5 +651,52 @@ if ( ! function_exists('_stringify_attributes'))
}
}
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('function_usable'))
+{
+ /**
+ * Function usable
+ *
+ * Executes a function_exists() check, and if the Suhosin PHP
+ * extension is loaded - checks whether the function that is
+ * checked might be disabled in there as well.
+ *
+ * This is useful as function_exists() will return FALSE for
+ * functions disabled via the *disable_functions* php.ini
+ * setting, but not for *suhosin.executor.func.blacklist* and
+ * *suhosin.executor.disable_eval*. These settings will just
+ * terminate script execution if a disabled function is executed.
+ *
+ * @link http://www.hardened-php.net/suhosin/
+ * @param string $function_name Function to check for
+ * @return bool TRUE if the function exists and is safe to call,
+ * FALSE otherwise.
+ */
+ function function_usable($function_name)
+ {
+ static $_suhosin_func_blacklist;
+
+ if (function_exists($function_name))
+ {
+ if ( ! isset($_suhosin_func_blacklist))
+ {
+ $_suhosin_func_blacklist = extension_loaded('suhosin')
+ ? array()
+ : explode(',', trim(@ini_get('suhosin.executor.func.blacklist')));
+
+ if ( ! in_array('eval', $_suhosin_func_blacklist, TRUE) && @ini_get('suhosin.executor.disable_eval'))
+ {
+ $_suhosin_func_blacklist[] = 'eval';
+ }
+ }
+
+ return in_array($function_name, $_suhosin_func_blacklist, TRUE);
+ }
+
+ return FALSE;
+ }
+}
+
/* End of file Common.php */
/* Location: ./system/core/Common.php */ \ No newline at end of file
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 9525f35d0..a9eec396c 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -871,7 +871,9 @@ class CI_Loader {
// If the PHP installation does not support short tags we'll
// do a little string replacement, changing the short tags
// to standard PHP echo statements.
- if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') === TRUE)
+ if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE
+ && config_item('rewrite_short_tags') === TRUE && function_usable('eval')
+ )
{
echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index f3718ae7e..d23be1af1 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1732,11 +1732,14 @@ class CI_Email {
*/
protected function _send_with_sendmail()
{
- $fp = @popen($this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t'.' -r '.$this->clean_email($this->_headers['Return-Path']), 'w');
-
- if ($fp === FALSE OR $fp === NULL)
+ // is popen() enabled?
+ if ( ! function_usable('popen')
+ OR FALSE === ($fp = @popen(
+ $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From'])
+ .' -t -r '.$this->clean_email($this->_headers['Return-Path'])
+ , 'w'))
+ ) // server probably has popen disabled, so nothing we can do to get a verbose error.
{
- // server probably has popen disabled, so nothing we can do to get a verbose error.
return FALSE;
}
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 3b453be47..9379e3ec8 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -867,7 +867,11 @@ class CI_Image_lib {
}
$retval = 1;
- @exec($cmd, $output, $retval);
+ // exec() might be disabled
+ if (function_usable('exec'))
+ {
+ @exec($cmd, $output, $retval);
+ }
// Did it work?
if ($retval > 0)
@@ -947,7 +951,11 @@ class CI_Image_lib {
$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
$retval = 1;
- @exec($cmd, $output, $retval);
+ // exec() might be disabled
+ if (function_usable('exec'))
+ {
+ @exec($cmd, $output, $retval);
+ }
// Did it work?
if ($retval > 0)
@@ -959,7 +967,7 @@ class CI_Image_lib {
// With NetPBM we have to create a temporary image.
// If you try manipulating the original it fails so
// we have to rename the temp file.
- copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
+ copy($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
unlink($this->dest_folder.'netpbm.tmp');
@chmod($this->full_dst_path, FILE_WRITE_MODE);
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 013644963..b3e9f7515 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -1208,7 +1208,7 @@ class CI_Upload {
? 'file --brief --mime '.escapeshellarg($file['tmp_name']).' 2>&1'
: 'file --brief --mime '.$file['tmp_name'].' 2>&1';
- if (function_exists('exec'))
+ if (function_usable('exec'))
{
/* This might look confusing, as $mime is being populated with all of the output when set in the second parameter.
* However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites
@@ -1223,7 +1223,7 @@ class CI_Upload {
}
}
- if ( (bool) @ini_get('safe_mode') === FALSE && function_exists('shell_exec'))
+ if ( (bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec'))
{
$mime = @shell_exec($cmd);
if (strlen($mime) > 0)
@@ -1237,7 +1237,7 @@ class CI_Upload {
}
}
- if (function_exists('popen'))
+ if (function_usable('popen'))
{
$proc = @popen($cmd, 'r');
if (is_resource($proc))
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index f4cb90c71..dfb21a210 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -54,6 +54,7 @@ Release Date: Not Released
- Changed environment defaults to report all errors in *development* and only fatal ones in *testing*, *production* but only display them in *development*.
- Updated *ip_address* database field lengths from 16 to 45 for supporting IPv6 address on :doc:`Trackback Library <libraries/trackback>` and :doc:`Captcha Helper <helpers/captcha_helper>`.
- Removed *cheatsheets* and *quick_reference* PDFs from the documentation.
+ - Added availability checks where usage of dangerous functions like ``eval()`` and ``exec()`` is required.
- Helpers
@@ -270,6 +271,7 @@ Release Date: Not Released
- Removed redundant conditional to determine HTTP server protocol in ``set_status_header()``.
- Changed ``_exception_handler()`` to respect php.ini *display_errors* setting.
- Added function ``is_https()`` to check if a secure connection is used.
+ - Added function ``function_usable()`` to check if a function exists and is not disabled by `Suhosin <http://www.hardened-php.net/suhosin/>`.
- Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE).
- Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library <general/hooks>`.
- :doc:`Output Library <libraries/output>` changes include:
diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst
index 7f327f00b..22f8d1942 100644
--- a/user_guide_src/source/general/common_functions.rst
+++ b/user_guide_src/source/general/common_functions.rst
@@ -93,4 +93,17 @@ is_https()
==========
Returns TRUE if a secure (HTTPS) connection is used and FALSE
-in any other case (including non-HTTP requests). \ No newline at end of file
+in any other case (including non-HTTP requests).
+
+function_usable($function_name)
+===============================
+
+Returns TRUE if a function exists and is usable, FALSE otherwise.
+
+This function runs a ``function_exists()`` check and if the
+`Suhosin extension <http://www.hardened-php.net/suhosin/>` is loaded,
+checks if it doesn't disable the function being checked.
+
+It is useful if you want to check for the availability of functions
+such as ``eval()`` and ``exec()``, which are dangerous and might be
+disabled on servers with highly restrictive security policies. \ No newline at end of file