feat: implement safe title processing in MainContent, MainContentTabbed, and MainContentTabless

- Introduced a new function `processTitle` to safely handle page titles by replacing PHP variables with their values without using eval.
- Updated title handling in MainContent, MainContentTabbed, and MainContentTabless to utilize the new `processTitle` function, enhancing security and maintainability.
This commit is contained in:
Zack Spear
2025-05-09 13:23:03 -07:00
parent 4ab619b94a
commit 9d0db98241
3 changed files with 26 additions and 10 deletions
@@ -13,6 +13,27 @@ $tabbed = $display['tabs'] == 0 && count($pages) > 1;
$contentInclude = $tabbed ? 'MainContentTabbed.php' : 'MainContentTabless.php';
$defaultIcon = "<i class=\"icon-app PanelIcon\"></i>";
/**
* Safely processes page titles by replacing PHP variables with their values
*
* @param string $rawTitle The unprocessed title that may contain variable references
* @return string Processed title with variables substituted
*/
function processTitle($rawTitle) {
// Safely replace any variables in the title without eval
$title = htmlspecialchars((string)$rawTitle);
return preg_replace_callback(
'/\$([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/',
function($matches) {
return isset($GLOBALS[$matches[1]]) ?
htmlspecialchars((string)$GLOBALS[$matches[1]]) :
'$'.$matches[1];
},
$title
);
}
function process_icon($icon, $docroot, $root) {
global $defaultIcon;
if (substr($icon, -4) == '.png') {
@@ -44,8 +65,8 @@ function process_icon($icon, $docroot, $root) {
* @return string HTML for the Panel element
*/
function generatePanel($pg, $path, $defaultIcon, $docroot, $useTabCookie = false) {
$panelTitle = ''; // to appease the linter because eval is used below
eval("\$panelTitle=\"".htmlspecialchars((string)$pg['Title'])."\";"); // ensures variables in any .page title are used
// Process title using our safe variable substitution function
$panelTitle = processTitle($pg['Title']);
$icon = _var($pg, 'Icon', $defaultIcon);
$icon = process_icon($icon, $docroot, $pg['root']);
@@ -10,10 +10,7 @@
<? $i = 0; ?>
<? foreach ($pages as $page): ?>
<? if (!isset($page['Title'])) continue; ?>
<?
/** ensures variables in any .page title are used */
eval("\$title=\"".htmlspecialchars((string)$page['Title'])."\";");
?>
<? $title = processTitle($page['Title']); ?>
<? $tabId = "tab" . ($i+1); ?>
<button
role="tab"
@@ -35,6 +32,7 @@
if (!isset($page['Title'])) {
continue;
}
$title = processTitle($page['Title']);
$tabId = "tab" . ($i+1);
annotate($page['file']);
?>
@@ -11,10 +11,7 @@
<? if (isset($page['Title'])): ?>
<div class="title">
<?
/** ensures variables in any .page title are used */
eval("\$title=\"".htmlspecialchars((string)$page['Title'])."\";");
?>
<? $title = processTitle($page['Title']); ?>
<?= tab_title($title, $page['root'], _var($page, 'Tag', false)) ?>
</div>
<? endif; ?>