diff options
Diffstat (limited to 'modules/gallery')
-rw-r--r-- | modules/gallery/tests/Xss_Security_Test.php | 53 | ||||
-rw-r--r-- | modules/gallery/views/admin_advanced_settings.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/admin_block_photo_stream.html.php | 4 | ||||
-rw-r--r-- | modules/gallery/views/admin_modules.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/admin_themes.html.php | 12 | ||||
-rw-r--r-- | modules/gallery/views/after_install.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/after_install_loader.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/l10n_client.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/move_browse.html.php | 2 | ||||
-rw-r--r-- | modules/gallery/views/permissions_form.html.php | 42 | ||||
-rw-r--r-- | modules/gallery/views/simple_uploader.html.php | 2 |
11 files changed, 80 insertions, 45 deletions
diff --git a/modules/gallery/tests/Xss_Security_Test.php b/modules/gallery/tests/Xss_Security_Test.php index 05fc052a..7a6589bd 100644 --- a/modules/gallery/tests/Xss_Security_Test.php +++ b/modules/gallery/tests/Xss_Security_Test.php @@ -34,6 +34,7 @@ class Xss_Security_Test extends Unit_Test_Case { $in_script_block = false; $inline_html = ""; $in_attribute_js_context = false; + $in_attribute = false; $href_attribute_start = false; $preceded_by_quote = false; @@ -87,23 +88,31 @@ class Xss_Security_Test extends Unit_Test_Case { } } - $href_attribute_start = preg_match('{\bhref\s*=\s*[\'"]?\s*$}i', $inline_html); - $preceded_by_quote = preg_match('{[\'"]\s*$}i', $inline_html); $pos = false; - if ($in_attribute_js_context && ($pos = strpos($inline_html, $delimiter)) !== false) { + if (($in_attribute || $in_attribute_js_context) && + ($pos = strpos($inline_html, $delimiter)) !== false) { $in_attribute_js_context = false; + $in_attribute = false; + $href_attribute_start = false; } - if (!$in_attribute_js_context) { + if (!$in_attribute_js_context || !$in_attribute) { $pos = ($pos === false) ? 0 : $pos; if (preg_match('{\bhref\s*=\s*(")javascript:[^"]*$}i', $inline_html, $matches, 0, $pos) || preg_match("{\bhref\s*=\s*(')javascript:[^']*$}i", $inline_html, $matches, 0, $pos) || preg_match("{\bon[a-z]+\s*=\s*(')[^']*$}i", $inline_html, $matches, 0, $pos) || preg_match('{\bon[a-z]+\s*=\s*(")[^"]*$}i', $inline_html, $matches, 0, $pos)) { $in_attribute_js_context = true; + $in_attribute = true; $delimiter = $matches[1]; $inline_html = ""; + } else if (preg_match('{\b([a-z]+)\s*=\s*(")([^"]*)$}i', $inline_html, $matches, 0, $pos) || + preg_match("{\b([a-z]+)\s*=\s*(')([^']*)$}i", $inline_html, $matches, 0, $pos)) { + $in_attribute = true; + $delimiter = $matches[2]; + $inline_html = ""; + $href_attribute_start = strtolower($matches[1]) == "href" && empty($matches[3]); } } @@ -117,7 +126,7 @@ class Xss_Security_Test extends Unit_Test_Case { // No need for a stack here - assume < ? = cannot be nested. $frame = self::_create_frame($token, $in_script_block, $href_attribute_start, $in_attribute_js_context, - $preceded_by_quote); + $in_attribute, $preceded_by_quote); $href_attribute_start = false; } else if ($frame && $token[0] == T_CLOSE_TAG) { // Store the < ? = ... ? > block that just ended here. @@ -207,6 +216,7 @@ class Xss_Security_Test extends Unit_Test_Case { self::_token_matches("(", $tokens, $token_number + 3)) { $frame->is_safe_html(true); $frame->is_safe_href_attr(true); + $frame->is_safe_attr(true); $method = $tokens[$token_number + 2][1]; $frame->expr_append("::$method("); @@ -233,6 +243,9 @@ class Xss_Security_Test extends Unit_Test_Case { } else { $frame->is_safe_html(true); } + if ("clean_attribute" == $method) { + $frame->is_safe_attr(true); + } } } } else if ($frame && $token[0] == T_OBJECT_OPERATOR) { @@ -253,6 +266,9 @@ class Xss_Security_Test extends Unit_Test_Case { } else { $frame->is_safe_html(true); } + if ("for_html_attr" == $method) { + $frame->is_safe_attr(true); + } } } else if ($frame) { $frame->expr_append($token[1]); @@ -305,6 +321,11 @@ class Xss_Security_Test extends Unit_Test_Case { if ($frame->is_safe_href_attr()) { $state = "CLEAN"; } + } else if ($frame->in_attribute()) { + $state = "DIRTY_ATTR"; + if ($frame->is_safe_attr()) { + $state = "CLEAN"; + } } else { if ($frame->is_safe_html()) { $state = "CLEAN"; @@ -332,10 +353,10 @@ class Xss_Security_Test extends Unit_Test_Case { private static function _create_frame($token, $in_script_block, $href_attribute_start, $in_attribute_js_context, - $preceded_by_quote) { + $in_attribute, $preceded_by_quote) { return new Xss_Security_Test_Frame($token[2], $in_script_block, $href_attribute_start, $in_attribute_js_context, - $preceded_by_quote); + $in_attribute, $preceded_by_quote); } private static function _token_matches($expected_token, &$tokens, $token_number) { @@ -366,16 +387,19 @@ class Xss_Security_Test_Frame { private $_in_href_attribute = false; private $_is_safe_href_attr = false; private $_in_attribute_js_context = false; - private $_preceded_by_quote; + private $_in_attribute = false; + private $_preceded_by_quote = false; + private $_is_safe_attr = false; private $_line; function __construct($line_number, $in_script_block, $href_attribute_start, $in_attribute_js_context, - $preceded_by_quote) { + $in_attribute, $preceded_by_quote) { $this->_line = $line_number; $this->_in_script_block = $in_script_block; $this->_in_href_attribute = $href_attribute_start; $this->_in_attribute_js_context = $in_attribute_js_context; + $this->_in_attribute = $in_attribute; $this->_preceded_by_quote = $preceded_by_quote; } @@ -395,6 +419,10 @@ class Xss_Security_Test_Frame { return $this->_in_href_attribute; } + function in_attribute() { + return $this->_in_attribute; + } + function in_attribute_js_context() { return $this->_in_attribute_js_context; } @@ -413,6 +441,13 @@ class Xss_Security_Test_Frame { return $this->_is_safe_href_attr; } + function is_safe_attr($new_val=NULL) { + if ($new_val !== NULL) { + $this->_is_safe_attr = (bool) $new_val; + } + return $this->_is_safe_attr; + } + function is_safe_js($new_val=NULL) { if ($new_val !== NULL) { $this->_is_safe_js = (bool) $new_val; diff --git a/modules/gallery/views/admin_advanced_settings.html.php b/modules/gallery/views/admin_advanced_settings.html.php index 4235e8f8..c3595da5 100644 --- a/modules/gallery/views/admin_advanced_settings.html.php +++ b/modules/gallery/views/admin_advanced_settings.html.php @@ -24,7 +24,7 @@ <td> <a href="<?= url::site("admin/advanced_settings/edit/$var->module_name/" . html::clean($var->name)) ?>" class="gDialogLink" - title="<?= t("Edit %var (%module_name)", array("var" => $var->name, "module_name" => $var->module_name)) ?>"> + title="<?= t("Edit %var (%module_name)", array("var" => $var->name, "module_name" => $var->module_name))->for_html_attr() ?>"> <? if ($var->value): ?> <?= html::clean($var->value) ?> <? else: ?> diff --git a/modules/gallery/views/admin_block_photo_stream.html.php b/modules/gallery/views/admin_block_photo_stream.html.php index a50836ad..1b9d8ff5 100644 --- a/modules/gallery/views/admin_block_photo_stream.html.php +++ b/modules/gallery/views/admin_block_photo_stream.html.php @@ -2,9 +2,9 @@ <ul> <? foreach ($photos as $photo): ?> <li class="gItem gPhoto"> - <a href="<?= url::site("photos/$photo->id") ?>" title="<?= html::clean($photo->title) ?>"> + <a href="<?= url::site("photos/$photo->id") ?>" title="<?= html::purify($photo->title)->for_html_attr() ?>"> <img <?= photo::img_dimensions($photo->width, $photo->height, 72) ?> - src="<?= $photo->thumb_url() ?>" alt="<?= html::clean($photo->title) ?>" /> + src="<?= $photo->thumb_url() ?>" alt="<?= html::purify($photo->title)->for_html_attr() ?>" /> </a> </li> <? endforeach ?> diff --git a/modules/gallery/views/admin_modules.html.php b/modules/gallery/views/admin_modules.html.php index 168e20d0..9cf03cb3 100644 --- a/modules/gallery/views/admin_modules.html.php +++ b/modules/gallery/views/admin_modules.html.php @@ -27,6 +27,6 @@ <? $i++ ?> <? endforeach ?> </table> - <input type="submit" value="<?= t("Update") ?>"/> + <input type="submit" value="<?= t("Update")->for_html_attr() ?>"/> </form> </div> diff --git a/modules/gallery/views/admin_themes.html.php b/modules/gallery/views/admin_themes.html.php index dc13a6a0..0aac4717 100644 --- a/modules/gallery/views/admin_themes.html.php +++ b/modules/gallery/views/admin_themes.html.php @@ -16,7 +16,7 @@ <h2> <?= t("Gallery theme") ?> </h2> <div class="gBlock gSelected"> <img src="<?= url::file("themes/{$site}/thumbnail.png") ?>" - alt="<?= $themes[$site]->name ?>" /> + alt="<?= html::clean_attribute($themes[$site]->name) ?>" /> <h3> <?= $themes[$site]->name ?> </h3> <p> <?= $themes[$site]->description ?> @@ -30,9 +30,9 @@ <? if (!$info->site) continue ?> <? if ($id == $site) continue ?> <div class="gBlock"> - <a href="<?= url::site("admin/themes/preview/site/$id") ?>" class="gDialogLink" title="<?= t("Theme Preview: %theme_name", array("theme_name" => $info->name)) ?>"> + <a href="<?= url::site("admin/themes/preview/site/$id") ?>" class="gDialogLink" title="<?= t("Theme Preview: %theme_name", array("theme_name" => $info->name))->for_html_attr() ?>"> <img src="<?= url::file("themes/{$id}/thumbnail.png") ?>" - alt="<?= $info->name ?>" /> + alt="<?= html::clean_attribute($info->name) ?>" /> <h3> <?= $info->name ?> </h3> <p> <?= $info->description ?> @@ -54,7 +54,7 @@ <h2> <?= t("Admin theme") ?> </h2> <div class="gBlock gSelected"> <img src="<?= url::file("themes/{$admin}/thumbnail.png") ?>" - alt="<?= $themes[$admin]->name ?>" /> + alt="<?= html::clean_attribute($themes[$admin]->name) ?>" /> <h3> <?= $themes[$admin]->name ?> </h3> <p> <?= $themes[$admin]->description ?> @@ -68,9 +68,9 @@ <? if (!$info->admin) continue ?> <? if ($id == $admin) continue ?> <div class="gBlock"> - <a href="<?= url::site("admin/themes/preview/admin/$id") ?>" class="gDialogLink" title="<?= t("Theme Preview: %theme_name", array("theme_name" => $info->name)) ?>"> + <a href="<?= url::site("admin/themes/preview/admin/$id") ?>" class="gDialogLink" title="<?= t("Theme Preview: %theme_name", array("theme_name" => $info->name))->for_html_attr() ?>"> <img src="<?= url::file("themes/{$id}/thumbnail.png") ?>" - alt="<?= $info->name ?>" /> + alt="<?= html::clean_attribute($info->name) ?>" /> <h3> <?= $info->name ?> </h3> <p> <?= $info->description ?> diff --git a/modules/gallery/views/after_install.html.php b/modules/gallery/views/after_install.html.php index b77a1707..897946a2 100644 --- a/modules/gallery/views/after_install.html.php +++ b/modules/gallery/views/after_install.html.php @@ -13,7 +13,7 @@ <p> <a href="<?= url::site("form/edit/users/{$user->id}") ?>" - title="<?= t("Edit Your Profile") ?>" + title="<?= t("Edit Your Profile")->for_html_attr() ?>" id="gAfterInstallChangePasswordLink" class="gButtonLink ui-state-default ui-corners-all"><?= t("Change Password Now") ?></a> <script> $("#gAfterInstallChangePasswordLink").gallery_dialog(); diff --git a/modules/gallery/views/after_install_loader.html.php b/modules/gallery/views/after_install_loader.html.php index 54484963..c2e3e1d9 100644 --- a/modules/gallery/views/after_install_loader.html.php +++ b/modules/gallery/views/after_install_loader.html.php @@ -1,6 +1,6 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <span id="gAfterInstall" - title="<?= t("Welcome to Gallery 3") ?>" + title="<?= t("Welcome to Gallery 3")->for_html_attr() ?>" href="<?= url::site("after_install") ?>"/> <script type="text/javascript"> $(document).ready(function(){$("#gAfterInstall").gallery_dialog({immediate: true});}); diff --git a/modules/gallery/views/l10n_client.html.php b/modules/gallery/views/l10n_client.html.php index c68a63c8..3a43f7d3 100644 --- a/modules/gallery/views/l10n_client.html.php +++ b/modules/gallery/views/l10n_client.html.php @@ -66,7 +66,7 @@ (<a href="http://www.unicode.org/cldr/data/charts/supplemental/language_plural_rules.html"><?= t("learn more about plural forms") ?></a>) <?= form::textarea("l10n-edit-plural-translation-other", "", ' rows="2"') ?> </div> - <input type="submit" name="l10n-edit-save" value="<?= t("Save translation") ?>"/> + <input type="submit" name="l10n-edit-save" value="<?= t("Save translation")->for_html_attr() ?>"/> <a href="javascript: Gallery.l10nClient.copySourceText()" class="gButtonLink ui-state-default ui-corner-all"><?= t("Copy source text") ?></a> </form> diff --git a/modules/gallery/views/move_browse.html.php b/modules/gallery/views/move_browse.html.php index 4f69c0e9..99728ecc 100644 --- a/modules/gallery/views/move_browse.html.php +++ b/modules/gallery/views/move_browse.html.php @@ -42,6 +42,6 @@ <form method="post" action="<?= url::site("move/save/$source->id") ?>"> <?= access::csrf_form_field() ?> <input type="hidden" name="target_id" value="" /> - <input type="submit" id="gMoveButton" value="<?= t("Move") ?>" disabled="disabled"/> + <input type="submit" id="gMoveButton" value="<?= t("Move")->for_html_attr() ?>" disabled="disabled"/> </form> </div> diff --git a/modules/gallery/views/permissions_form.html.php b/modules/gallery/views/permissions_form.html.php index e6b217c5..a0bb35f2 100644 --- a/modules/gallery/views/permissions_form.html.php +++ b/modules/gallery/views/permissions_form.html.php @@ -20,9 +20,9 @@ <? if ($lock): ?> <td class="gDenied"> - <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" title="<?= t('denied and locked through parent album') ?>" alt="<?= t('denied icon') ?>" /> - <a href="javascript:show(<?= $lock->id ?>)" title="<?= t('click to go to parent album') ?>"> - <img src="<?= url::file('themes/default/images/ico-lock.png') ?>" alt="<?= t('locked icon') ?>" /> + <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" title="<?= t('denied and locked through parent album')->for_html_attr() ?>" alt="<?= t('denied icon')->for_html_attr() ?>" /> + <a href="javascript:show(<?= $lock->id ?>)" title="<?= t('click to go to parent album')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-lock.png') ?>" alt="<?= t('locked icon')->for_html_attr() ?>" /> </a> </td> <? else: ?> @@ -30,23 +30,23 @@ <? if ($allowed): ?> <td class="gAllowed"> <a href="javascript:set('allow',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('allowed through parent album, click to allow explicitly') ?>"> - <img src="<?= url::file('themes/default/images/ico-success-pale.png') ?>" alt="<?= t('passive allowed icon') ?>" /> + title="<?= t('allowed through parent album, click to allow explicitly')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-success-pale.png') ?>" alt="<?= t('passive allowed icon')->for_html_attr() ?>" /> </a> <a href="javascript:set('deny',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('click to deny') ?>"> - <img src="<?= url::file('themes/default/images/ico-denied-gray.png') ?>" alt="<?= t('inactive denied icon') ?>" /> + title="<?= t('click to deny')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-denied-gray.png') ?>" alt="<?= t('inactive denied icon')->for_html_attr() ?>" /> </a> </td> <? else: ?> <td class="gDenied"> <a href="javascript:set('allow',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('click to allow') ?>"> - <img src="<?= url::file('themes/default/images/ico-success-gray.png') ?>" alt="<?= t('inactive allowed icon') ?>" /> + title="<?= t('click to allow')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-success-gray.png') ?>" alt="<?= t('inactive allowed icon')->for_html_attr() ?>" /> </a> <a href="javascript:set('deny',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('denied through parent album, click to deny explicitly') ?>"> - <img src="<?= url::file('themes/default/images/ico-denied-pale.png') ?>" alt="<?= t('passive denied icon') ?>" /> + title="<?= t('denied through parent album, click to deny explicitly')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-denied-pale.png') ?>" alt="<?= t('passive denied icon')->for_html_attr() ?>" /> </a> </td> <? endif ?> @@ -54,31 +54,31 @@ <? elseif ($intent === access::DENY): ?> <td class="gDenied"> <a href="javascript:set('allow',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('click to allow') ?>"> - <img src="<?= url::file('themes/default/images/ico-success-gray.png') ?>" alt="<?= t('inactive allowed icon') ?>" /> + title="<?= t('click to allow')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-success-gray.png') ?>" alt="<?= t('inactive allowed icon')->for_html_attr() ?>" /> </a> <? if ($item->id == 1): ?> - <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" alt="<?= t('denied icon') ?>" title="<?= t('denied') ?>"/> + <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" alt="<?= t('denied icon')->for_html_attr() ?>" title="<?= t('denied')->for_html_attr() ?>"/> <? else: ?> <a href="javascript:set('reset',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('denied, click to reset') ?>"> - <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" alt="<?= t('denied icon') ?>" /> + title="<?= t('denied, click to reset')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-denied.png') ?>" alt="<?= t('denied icon')->for_html_attr() ?>" /> </a> <? endif ?> </td> <? elseif ($intent === access::ALLOW): ?> <td class="gAllowed"> <? if ($item->id == 1): ?> - <img src="<?= url::file('themes/default/images/ico-success.png') ?>" title="<?= t("allowed") ?>" alt="<?= t('allowed icon') ?>" /> + <img src="<?= url::file('themes/default/images/ico-success.png') ?>" title="<?= t("allowed")->for_html_attr() ?>" alt="<?= t('allowed icon')->for_html_attr() ?>" /> <? else: ?> <a href="javascript:set('reset',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('allowed, click to reset') ?>"> - <img src="<?= url::file('themes/default/images/ico-success.png') ?>" alt="<?= t('allowed icon') ?>" /> + title="<?= t('allowed, click to reset')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-success.png') ?>" alt="<?= t('allowed icon')->for_html_attr() ?>" /> </a> <? endif ?> <a href="javascript:set('deny',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)" - title="<?= t('click to deny') ?>"> - <img src="<?= url::file('themes/default/images/ico-denied-gray.png') ?>" alt="<?= t('inactive denied icon') ?>" /> + title="<?= t('click to deny')->for_html_attr() ?>"> + <img src="<?= url::file('themes/default/images/ico-denied-gray.png') ?>" alt="<?= t('inactive denied icon')->for_html_attr() ?>" /> </a> </td> <? endif ?> diff --git a/modules/gallery/views/simple_uploader.html.php b/modules/gallery/views/simple_uploader.html.php index 9cf554ec..7f8a96df 100644 --- a/modules/gallery/views/simple_uploader.html.php +++ b/modules/gallery/views/simple_uploader.html.php @@ -35,7 +35,7 @@ <span id="gUploadQueueInfo"> <?= t("Upload Queue") ?> </span> - <a id="gUploadCancel" title="<?= t("Cancel all the pending uploads") ?>" onclick="swfu.cancelQueue();"><?= t("cancel") ?></a> + <a id="gUploadCancel" title="<?= t("Cancel all the pending uploads")->for_html_attr() ?>" onclick="swfu.cancelQueue();"><?= t("cancel") ?></a> </p> <div id="gAddPhotosCanvas" style="text-align: center;"> <div id="gAddPhotosQueue"></div> |