AbsaOSS / AbsaOSS/knowledge-base

Inline event handlers in sub-app HTML survive the build: dead under CSP, and a dark-mode leak without it

Abierto
#67 0 comentarios 0 reacciones 1 asignado Reclamado por @oto-macenauer-absa Ver en GitHub
Lenguaje dominante
JavaScript
Estrellas
0
Forks
0
Merge medio
7 h 35 min
PR fusionados (30 d)
22

Descripción

## Summary

The "nothing inline in the output" invariant is enforced for `` elements only. Inline **event-handler attributes** are neither hoisted nor stripped, and `script-src 'self'` blocks them exactly like an inline script.

The vendored docs-example fixture ships one, and it reaches `dist/`:

```html
<button id="theme-toggle" aria-label="Toggle theme" onclick="
const r=document.getElementById('docs-root');
r.classList.toggle('dark');
localStorage.setItem('theme',r.classList.contains('dark')?'dark':'light');
">
```

## Two problems

1. **It is dead code in production.** `script-src 'self'` with no `'unsafe-inline'` blocks inline handlers, so the button is inert and logs a CSP violation when clicked. `scripts/hoist-inline-scripts.js` exists precisely so that already-published bundles keep working under the policy; it does not cover this case, so any doc app whose interactivity is written as `onclick=` is quietly broken instead.
2. **It is a light-only leak wherever the CSP is absent.** `astro dev` and `astro preview` serve no CSP, so there the toggle works and adds `dark` to the sub-app root — the exact thing `transform.js` strips the theme bootstrap to prevent (#48).

`tests/build-integrity.spec.js` asserts every `<script>` has a `src`, which is why this got through. Nothing asserts on `on*` attributes.

## Suggested fix

Decide between the two available policies and apply it in `src/utils/transform.js`, where the document is already parsed:

- **Strip `on*` attributes.** Honest about what production does — the handler cannot run anyway — and closes the dev-mode dark leak. Cost: a doc app's inline interactivity disappears rather than failing loudly.
- **Hoist them**, the way `<script>` bodies are hoisted: turn `onclick="…"` into a listener registered from a generated file. Preserves behaviour, but needs a stable element handle and is a good deal more machinery.

Either way, add the assertion to `tests/build-integrity.spec.js` so the invariant covers attributes and not just elements, and say so in `contract/HEADLESS_RULES.md` — this is a rule onboarding repositories need to know about.

Separately worth deciding whether the docs-example fixture should keep shipping a dark-mode toggle at all, given the marketplace is light-only.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.