feat(guards): add GR-SEC-010 — output escaping enforcement in views
Add architecture test ViewLayerOutputEscapingContractTest that flags raw <?php echo in .phtml files. Legitimate uses (pre-built ARIA attrs from navActive(), hardcoded role values, pre-rendered HTML fragments) must carry an inline // raw-html-ok: reason marker. Annotated all 11 existing raw echo sites with justification markers. Added guard to catalog, enforcement map (automated), CLAUDE.md security section, and never-do-this list. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,7 @@ $timeouts = [
|
||||
<?php $type = $message['type'] ?? 'info'; ?>
|
||||
<?php $timeout = $timeouts[$type] ?? 5000; ?>
|
||||
<?php $isAssertive = $type === 'error' || $type === 'warning'; ?>
|
||||
<div class="notice" data-variant="<?php e($type); ?>" data-flash-timeout="<?php e($timeout); ?>" role="<?php echo $isAssertive ? 'alert' : 'status'; ?>">
|
||||
<div class="notice" data-variant="<?php e($type); ?>" data-flash-timeout="<?php e($timeout); ?>" role="<?php echo $isAssertive ? 'alert' : 'status'; // raw-html-ok: hardcoded ARIA role values ?>">
|
||||
<span><?php e(t($message['message'] ?? '')); ?></span>
|
||||
<form method="post" action="flash/dismiss/<?php e($message['id'] ?? ''); ?>">
|
||||
<input type="hidden" name="return" value="<?php e($returnTarget); ?>">
|
||||
|
||||
@@ -12,7 +12,7 @@ if (!in_array($listTitleTag, $allowedTitleTags, true)) {
|
||||
<<?php e($listTitleTag); ?>><?php e($listTitle); ?></<?php e($listTitleTag); ?>>
|
||||
<?php if (trim($listTitleActionsHtml) !== ''): ?>
|
||||
<div class="app-list-titlebar-actions">
|
||||
<?php echo $listTitleActionsHtml; ?>
|
||||
<?php echo $listTitleActionsHtml; // raw-html-ok: pre-built HTML from titlebar action renderer ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -255,7 +255,7 @@ $renderAdminNavGroup = static function (array $group, string $tenantQueryParam):
|
||||
$active = $item['active'] ?? ['class' => '', 'aria' => ''];
|
||||
?>
|
||||
<li>
|
||||
<a href="<?php e($href); ?>" class="<?php e($active['class'] ?? ''); ?>" <?php echo $active['aria'] ?? ''; ?>>
|
||||
<a href="<?php e($href); ?>" class="<?php e($active['class'] ?? ''); ?>" <?php echo $active['aria'] ?? ''; // raw-html-ok: pre-built ARIA attribute from navActive() ?>>
|
||||
<?php e($item['label'] ?? ''); ?>
|
||||
</a>
|
||||
</li>
|
||||
@@ -306,7 +306,7 @@ $modulePanelSlots = is_array($moduleSlots['aside.tab_panel'] ?? null) ? $moduleS
|
||||
<ul>
|
||||
<li>
|
||||
<?php $home = navActive(['', 'admin'], false); ?>
|
||||
<a href="<?php e(lurl('')); ?>" class="<?php e($home['class']); ?>" <?php echo $home['aria']; ?>>
|
||||
<a href="<?php e(lurl('')); ?>" class="<?php e($home['class']); ?>" <?php echo $home['aria']; // raw-html-ok: pre-built ARIA attribute from navActive() ?>>
|
||||
<?php e(t('Home')); ?>
|
||||
</a>
|
||||
</li>
|
||||
@@ -325,7 +325,7 @@ $modulePanelSlots = is_array($moduleSlots['aside.tab_panel'] ?? null) ? $moduleS
|
||||
?>
|
||||
<li>
|
||||
<a href="<?php e($explorerHref); ?>" class="<?php e($explorerActive['class'] ?? ''); ?>"
|
||||
<?php echo $explorerActive['aria'] ?? ''; ?>>
|
||||
<?php echo $explorerActive['aria'] ?? ''; // raw-html-ok: pre-built ARIA attribute from navActive() ?>>
|
||||
<?php e(t($explorerLabel)); ?>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -33,7 +33,7 @@ $style = $styleParts ? implode(';', $styleParts) . ';' : '';
|
||||
|
||||
?>
|
||||
<a
|
||||
class="app-tile<?php echo $class ? ' ' . $class : ''; ?>"
|
||||
class="app-tile<?php echo $class ? ' ' . $class : ''; // raw-html-ok: internal CSS class from tile config ?>"
|
||||
href="<?php e($href); ?>"
|
||||
<?php if ($style) : ?>style="<?php e($style); ?>"<?php endif; ?>
|
||||
<?php if ($tooltip !== '') : ?>data-tooltip="<?php e($tooltip); ?>" data-tooltip-pos="<?php e($tooltipPos); ?>"<?php endif; ?>
|
||||
|
||||
@@ -135,7 +135,7 @@ $moduleTopbarSlots = is_array($moduleSlots['topbar.right_item'] ?? null) ? $modu
|
||||
data-theme-option
|
||||
data-theme-value="<?php e($key); ?>"
|
||||
class="<?php e($isActiveTheme ? 'active' : ''); ?>"
|
||||
<?php echo $isActiveTheme ? 'aria-current="true"' : ''; ?>>
|
||||
<?php echo $isActiveTheme ? 'aria-current="true"' : ''; // raw-html-ok: hardcoded ARIA attribute ?>>
|
||||
<?php e(t($label)); ?>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user