diff options
-rw-r--r-- | CHANGES.txt | 42 | ||||
-rw-r--r-- | CONTRIBUTORS.txt | 5 | ||||
-rw-r--r-- | actions/profile/edit.php | 4 | ||||
-rw-r--r-- | engine/lib/output.php | 42 | ||||
-rw-r--r-- | engine/lib/upgrades/2010052601.php | 12 | ||||
-rw-r--r-- | install/ElggInstaller.php | 2 | ||||
-rw-r--r-- | install/cli/sample_installer.php | 35 | ||||
-rw-r--r-- | mod/blog/views/default/forms/blog/save.php | 2 | ||||
-rw-r--r-- | mod/groups/actions/groups/edit.php | 8 | ||||
-rw-r--r-- | mod/messages/pages/messages/read.php | 2 | ||||
-rw-r--r-- | version.php | 4 | ||||
-rw-r--r-- | views/default/output/email.php | 4 |
12 files changed, 142 insertions, 20 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 7a3422d7d..5eb9aca0d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,45 @@ +Version 1.8.9 +(November 11, 2012 from https://github.com/Elgg/Elgg/tree/1.8) + + Contributing Developers: + * Brett Profitt + * Cash Costello + * Evan Winslow + * Jeroen Dalsem + * Jerome Bakker + * Matt Beckett + * Paweł Sroka + * Sem + * Steve Clay + + Security Enhancements: + * Sample CLI installer cannot break site + * Removed XSS vulnerabilities in titles and user profiles + + Enhancements: + * UX: A group's owner can transfer ownership to another member + * UX: Search queries persist in the search box + * Several (X)HTML validation improvements + * Improved performance via more aggressive entity and metadata caching + * BC: 1.7 group profile URLs forward correctly + + Bugfixes: + * UX: Titles containing HTML tokens are never mangled + * UX: Empty user profile values saved properly + * UX: Blog creator always mentioned in activity stream (not user who published it) + * UI: Fixed ordering of registered menu items in some cases + * UI: Embed dialog does not break file inputs + * UI: Datepicker now respects language + * UI: More reliable display of access input in widgets + * UI: Group edit form is sticky + * UI: Site categories are sticky in forms + * API: Language fallback works in Javascript + * API: Fallback to default viewtype if invalid one given + * API: Notices reported for missing language keys + * Memcache now safe to use; never bypasses access control + * BC: upgrade shows comments consistently in activity stream + + Version 1.8.8 (July 11, 2012 from https://github.com/Elgg/Elgg/tree/1.8) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0163757e7..a8e74d3a4 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -1,6 +1,7 @@ The following have made notable contributions to the Elgg Project. (List in alphabetical order.) +Steve Clay - http://www.mrclay.org/, https://twitter.com/mrclay_org Cash Costello - cash@elgg.org, http://cashcostello.com/ @@ -20,10 +21,10 @@ Tom Read - MITRE http://mitre.org/ Justin Richer - MITRE http://mitre.org/ -Dave Tosh - davidgtosh@gmail.com, http://twitter.com/davetosh +Dave Tosh - davidgtosh@gmail.com, http://twitter.com/davetosh Ben Werdmuller - http://benwerd.com/ -Nicholas Whitt - nick.whitt@gmail.com, http://twitter.com/nogoodnick +Nicholas Whitt - nick.whitt@gmail.com, http://twitter.com/nogoodnick Evan Winslow - evan@elgg.org, http://evanwinslow.com/ diff --git a/actions/profile/edit.php b/actions/profile/edit.php index b6d73ff2d..89bf2bc0b 100644 --- a/actions/profile/edit.php +++ b/actions/profile/edit.php @@ -25,7 +25,7 @@ if (!is_array($accesslevel)) { * wrapper for recursive array walk decoding */ function profile_array_decoder(&$v) { - $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8'); + $v = _elgg_html_decode($v); } $profile_fields = elgg_get_config('profile_fields'); @@ -37,7 +37,7 @@ foreach ($profile_fields as $shortname => $valuetype) { if (is_array($value)) { array_walk_recursive($value, 'profile_array_decoder'); } else { - $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8'); + $value = _elgg_html_decode($value); } // limit to reasonable sizes diff --git a/engine/lib/output.php b/engine/lib/output.php index 0069360f0..352de863b 100644 --- a/engine/lib/output.php +++ b/engine/lib/output.php @@ -398,3 +398,45 @@ function elgg_strip_tags($string) { return $string; } + +/** + * Apply html_entity_decode() to a string while re-entitising HTML + * special char entities to prevent them from being decoded back to their + * unsafe original forms. + * + * This relies on html_entity_decode() not translating entities when + * doing so leaves behind another entity, e.g. &gt; if decoded would + * create > which is another entity itself. This seems to escape the + * usual behaviour where any two paired entities creating a HTML tag are + * usually decoded, i.e. a lone > is not decoded, but <foo> would + * be decoded to <foo> since it creates a full tag. + * + * Note: This function is poorly explained in the manual - which is really + * bad given its potential for misuse on user input already escaped elsewhere. + * Stackoverflow is littered with advice to use this function in the precise + * way that would lead to user input being capable of injecting arbitrary HTML. + * + * @param string $string + * + * @return string + * + * @author Pádraic Brady + * @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com) + * @license Released under dual-license GPL2/MIT by explicit permission of Pádraic Brady + * + * @access private + */ +function _elgg_html_decode($string) { + $string = str_replace( + array('>', '<', '&', '"', '''), + array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'), + $string + ); + $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8'); + $string = str_replace( + array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'), + array('>', '<', '&', '"', '''), + $string + ); + return $string; +} diff --git a/engine/lib/upgrades/2010052601.php b/engine/lib/upgrades/2010052601.php index 5b477910f..a9cca6dc5 100644 --- a/engine/lib/upgrades/2010052601.php +++ b/engine/lib/upgrades/2010052601.php @@ -9,14 +9,14 @@ $params = array('type' => 'group', $groups = elgg_get_entities($params); if ($groups) { foreach ($groups as $group) { - $group->name = html_entity_decode($group->name, ENT_COMPAT, 'UTF-8'); - $group->description = html_entity_decode($group->description, ENT_COMPAT, 'UTF-8'); - $group->briefdescription = html_entity_decode($group->briefdescription, ENT_COMPAT, 'UTF-8'); - $group->website = html_entity_decode($group->website, ENT_COMPAT, 'UTF-8'); + $group->name = _elgg_html_decode($group->name); + $group->description = _elgg_html_decode($group->description); + $group->briefdescription = _elgg_html_decode($group->briefdescription); + $group->website = _elgg_html_decode($group->website); if ($group->interests) { $tags = $group->interests; - foreach ($tags as $index=>$tag) { - $tags[$index] = html_entity_decode($tag, ENT_COMPAT, 'UTF-8'); + foreach ($tags as $index => $tag) { + $tags[$index] = _elgg_html_decode($tag); } $group->interests = $tags; } diff --git a/install/ElggInstaller.php b/install/ElggInstaller.php index 03c84a43e..934b38d28 100644 --- a/install/ElggInstaller.php +++ b/install/ElggInstaller.php @@ -157,7 +157,7 @@ class ElggInstaller { 'password', ); foreach ($requiredParams as $key) { - if (!array_key_exists($key, $params)) { + if (empty($params[$key])) { $msg = elgg_echo('install:error:requiredfield', array($key)); throw new InstallationException($msg); } diff --git a/install/cli/sample_installer.php b/install/cli/sample_installer.php index 954169a6a..0bae0cd23 100644 --- a/install/cli/sample_installer.php +++ b/install/cli/sample_installer.php @@ -3,10 +3,27 @@ * Sample cli installer script */ +$enabled = false; + +// Do not edit below this line. ////////////////////////////// + + +if (!$enabled) { + echo "To enable this script, change \$enabled to true.\n"; + echo "You *must* disable this script after a successful installation.\n"; + exit; +} + +if (PHP_SAPI !== 'cli') { + echo "You must use the command line to run this script."; + exit; +} + require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php"); $installer = new ElggInstaller(); +// none of the following may be empty $params = array( // database parameters 'dbuser' => '', @@ -28,3 +45,21 @@ $params = array( // install and create the .htaccess file $installer->batchInstall($params, TRUE); + +// at this point installation has completed (otherwise an exception halted execution). + +// try to rewrite the script to disable it. +if (is_writable(__FILE__)) { + $code = file_get_contents(__FILE__); + if (preg_match('~\\$enabled\\s*=\\s*(true|1)\\s*;~i', $code)) { + // looks safe to rewrite + $code = preg_replace('~\\$enabled\\s*=\\s*(true|1)\\s*;~i', '$enabled = false;', $code); + file_put_contents(__FILE__, $code); + + echo "\nNote: This script has been disabled for your safety.\n"; + exit; + } +} + +echo "\nWarning: You *must* disable this script by setting \$enabled = false;.\n"; +echo "Leaving this script enabled could endanger your installation.\n"; diff --git a/mod/blog/views/default/forms/blog/save.php b/mod/blog/views/default/forms/blog/save.php index 0aefae0d9..7c3265c8d 100644 --- a/mod/blog/views/default/forms/blog/save.php +++ b/mod/blog/views/default/forms/blog/save.php @@ -53,7 +53,7 @@ $excerpt_label = elgg_echo('blog:excerpt'); $excerpt_input = elgg_view('input/text', array( 'name' => 'excerpt', 'id' => 'blog_excerpt', - 'value' => html_entity_decode($vars['excerpt'], ENT_COMPAT, 'UTF-8') + 'value' => _elgg_html_decode($vars['excerpt']) )); $body_label = elgg_echo('blog:body'); diff --git a/mod/groups/actions/groups/edit.php b/mod/groups/actions/groups/edit.php index a4169461a..2d7e1f023 100644 --- a/mod/groups/actions/groups/edit.php +++ b/mod/groups/actions/groups/edit.php @@ -8,15 +8,15 @@ // Load configuration global $CONFIG; +elgg_make_sticky_form('groups'); + /** * wrapper for recursive array walk decoding */ function profile_array_decoder(&$v) { - $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8'); + $v = _elgg_html_decode($v); } -elgg_make_sticky_form('groups'); - // Get group fields $input = array(); foreach ($CONFIG->group as $shortname => $valuetype) { @@ -25,7 +25,7 @@ foreach ($CONFIG->group as $shortname => $valuetype) { if (is_array($input[$shortname])) { array_walk_recursive($input[$shortname], 'profile_array_decoder'); } else { - $input[$shortname] = html_entity_decode($input[$shortname], ENT_COMPAT, 'UTF-8'); + $input[$shortname] = _elgg_html_decode($input[$shortname]); } if ($valuetype == 'tags') { diff --git a/mod/messages/pages/messages/read.php b/mod/messages/pages/messages/read.php index eb36eaa4b..a64623564 100644 --- a/mod/messages/pages/messages/read.php +++ b/mod/messages/pages/messages/read.php @@ -38,7 +38,7 @@ if ($inbox) { ); $body_params = array('message' => $message); $content .= elgg_view_form('messages/reply', $form_params, $body_params); - $from_user = get_user($message->fromID); + $from_user = get_user($message->fromId); if (elgg_get_logged_in_user_guid() == elgg_get_page_owner_guid() && $from_user) { elgg_register_menu_item('title', array( diff --git a/version.php b/version.php index dda087c52..a2417d848 100644 --- a/version.php +++ b/version.php @@ -11,7 +11,7 @@ // YYYYMMDD = Elgg Date // XX = Interim incrementer -$version = 2012071100; +$version = 2012111100; // Human-friendly version name -$release = '1.8.8'; +$release = '1.8.9'; diff --git a/views/default/output/email.php b/views/default/output/email.php index 00eefad1f..f5a8bc4b8 100644 --- a/views/default/output/email.php +++ b/views/default/output/email.php @@ -10,6 +10,8 @@ * */ +$encoded_value = htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8'); + if (!empty($vars['value'])) { - echo "<a href=\"mailto:" . $vars['value'] . "\">". htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8', false) ."</a>"; + echo "<a href=\"mailto:$encoded_value\">$encoded_value</a>"; }
\ No newline at end of file |