Selaa lähdekoodia

docs: mark SEC_REVIEW F55 as fixed by F24 (193f646)

F55 noted that `ips/detail.twig` interpolated `{{ x|json_encode|
e('html_attr') }}` directly inside an Alpine `x-data` expression —
escape-strategy mismatch (`html_attr` vs the JS evaluator Alpine
runs the attribute through), with backticks unescaped and Unicode
permissive.

The F24 CSP-tightening fix (commit 193f646) rewrote the
score-over-time chart wiring to the exact pattern F55 recommended:

  Before:
    x-data="scoreOverTime({
      reports: {{ score_chart.reports|json_encode|e('html_attr') }},
      categories: {{ score_chart.categories|json_encode|e('html_attr') }},
      now: '{{ score_chart.now }}'
    })"

  After:
    x-data="scoreOverTime"
    data-score-chart="{{ {reports: …, categories: …, now: …}
                         |json_encode|e('html_attr') }}"

`e('html_attr')` now escapes for the actual context (HTML
attribute), and `app.js` reads
`JSON.parse(this.$el.dataset.scoreChart)` — a string DOM read
followed by a JSON parse, never an Alpine `eval`. Same fix shape
as F53, applied to the same migration.

Closing F55 for bookkeeping; no new code change needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 3 päivää sitten
vanhempi
sitoutus
ee1582d904
1 muutettua tiedostoa jossa 21 lisäystä ja 1 poistoa
  1. 21 1
      doc/SEC_REVIEW.md

+ 21 - 1
doc/SEC_REVIEW.md

@@ -11,7 +11,7 @@
 >
 > Each finding is referenced as **F<N>** for later citation.
 >
-> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (22 fixed, 20 open).
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (23 fixed, 19 open).
 
 ---
 
@@ -1813,6 +1813,26 @@
   non-Alpine element and read via `dataset.foo` + `JSON.parse` (the
   pattern already used in `dashboard.twig`).
 - **Severity: 1**
+- **Status:** Fixed by the F24 fix (`193f646`), the same CSP-
+  tightening migration that resolved F53. The previously-vulnerable
+  pattern
+  ```html
+  x-data="scoreOverTime({
+    reports: {{ score_chart.reports|json_encode|e('html_attr') }},
+    ...
+  })"
+  ```
+  was rewritten to the exact pattern F55 recommended:
+  ```html
+  x-data="scoreOverTime"
+  data-score-chart="{{ {reports: …, categories: …, now: …}
+                       |json_encode|e('html_attr') }}"
+  ```
+  The `e('html_attr')` filter now escapes for the actual context
+  (HTML attribute), and `app.js` reads
+  `JSON.parse(this.$el.dataset.scoreChart)` — a string DOM read
+  followed by a JSON parse, never an Alpine eval. Closing F55 for
+  bookkeeping; no new code change needed.
 
 ### F56 — Inline `<script>` blocks in many templates force CSP `'unsafe-inline'`
 - **Files:** `ui/resources/views/pages/ips/detail.twig:274-392`,