Files
iaohkut fa6c123595 Fix stored XSS in ALE view by HTML-escaping piggy bank name
The Twig template ale.twig rendered the piggy bank name from
AuditLogEntry.after.piggy using |raw, bypassing auto-escaping.
A user-controlled name containing HTML (e.g. <img onerror=...>)
would execute as JavaScript in any browser viewing the transaction
audit log (CWE-79).

Apply |e filter to escape only the user-controlled `name` parameter
before substitution into the trans() string. The |raw filter is
preserved because the `amount` parameter legitimately contains
<span> tags for currency styling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 11:07:57 -04:00

119 lines
5.5 KiB
Twig

<table class="table" aria-label="Table">
<thead>
<tr>
<td colspan="3"><em>{{ 'incomplete_ale'|_ }}</em></td>
</tr>
</thead>
<tbody>
{% for logEntry in logEntries %}
<tr>
<th class="twenty" scope="row">
{# link to object: #}
{% if 'FireflyIII\\Models\\Rule' == logEntry.changer_type %}
<a href="{{ route('rules.edit', [logEntry.changer_id] ) }}">
{% endif %}
{% if 'FireflyIII\\User' == logEntry.changer_type %}
<a href="{{ route('profile.index') }}">
{% endif %}
{{ logEntry.changer_type|replace({"FireflyIII\\Models\\": ""})|replace({"FireflyIII\\": ""}) }} #{{ logEntry.changer_id }}
</a>
</th>
<td class="thirty" title="{{ logEntry.created_at.isoFormat(dateTimeFormat) }}">
{{ trans('firefly.ale_action_'~logEntry.action) }}
</td>
<td>
{# display depends on action #}
{% if 'add_tag' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'update_amount' == logEntry.action %}
{{ formatAmountBySymbol(logEntry.before.amount, logEntry.before.currency_symbol, logEntry.before.decimal_places, true) }}
&rarr;
{{ formatAmountBySymbol(logEntry.after.amount, logEntry.after.currency_symbol, logEntry.after.decimal_places, true) }}
{% endif %}
{% if 'update_foreign_amount' == logEntry.action %}
{{ formatAmountBySymbol(logEntry.before.amount, logEntry.before.currency_symbol, logEntry.before.decimal_places, true) }}
&rarr;
{{ formatAmountBySymbol(logEntry.after.amount, logEntry.after.currency_symbol, logEntry.after.decimal_places, true) }}
{% endif %}
{% if 'update_group_title' == logEntry.action %}
<code><s>{{ logEntry.before }}</s></code>
&rarr;
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'clear_category' == logEntry.action %}
<code><s>{{ logEntry.before }}</s></code>
{% endif %}
{% if 'clear_tag' == logEntry.action %}
<code><s>{{ logEntry.before }}</s></code>
{% endif %}
{% if 'clear_notes' == logEntry.action %}
{% if logEntry.before|length > 25 %}
<code><s>{{ logEntry.before|slice(0,25) }}...</s></code>
{% else %}
<code><s>{{ logEntry.before }}</s></code>
{% endif %}
{% endif %}
{% if 'set_bill' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'set_budget' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'set_category' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'set_source' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'set_destination' == logEntry.action %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'update_date' == logEntry.action %}
<code><s>{{ carbonize(logEntry.before).isoFormat(dateTimeFormat) }}</s></code>
&rarr;
<code>{{ carbonize(logEntry.after).isoFormat(dateTimeFormat) }}</code>
{% endif %}
{% if 'update_transaction_type' == logEntry.action %}
{{ trans('firefly.'~logEntry.before) }} &rarr; {{ trans('firefly.'~logEntry.after) }}
{% endif %}
{% if 'update_notes' == logEntry.action %}
{% if logEntry.before|length > 25 %}
<code><s>{{ logEntry.before|slice(0,25) }}...</s></code>
{% else %}
<code><s>{{ logEntry.before }}</s></code>
{% endif %}
&rarr;
{% if logEntry.after|length > 25 %}
<code>{{ logEntry.after|slice(0,25) }}...</code>
{% else %}
<code>{{ logEntry.after }}</code>
{% endif %}
{% endif %}
{% if 'update_description' == logEntry.action %}
<code><s>{{ logEntry.before }}</s></code>
&rarr;
<code>{{ logEntry.after }}</code>
{% endif %}
{% if 'add_to_piggy' == logEntry.action %}
{{ trans('firefly.ale_action_log_add', {amount: formatAmountBySymbol(logEntry.after.amount, logEntry.after.currency_symbol, logEntry.after.decimal_places, true), name: logEntry.after.piggy|e})|raw }}
{% endif %}
{% if 'remove_from_piggy' == logEntry.action %}
{{ trans('firefly.ale_action_log_remove', {amount: formatAmountBySymbol(logEntry.after.amount, logEntry.after.currency_symbol, logEntry.after.decimal_places, true), name: logEntry.after.piggy|e})|raw }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>