Two injection points.
Reflected, backend/server.js:505: values from the OAuth callback are interpolated into an inline <script> without escaping, so a crafted callback URL executes attacker script on your origin, with access to the signed-in Firebase session.
Stored, dashboard.html:1116: spark.thumbnail and spark.id are interpolated into innerHTML unescaped. Because any signed-in user can create a spark, one user can store script that runs in every other user's browser when the feed renders.
Should be
- Never interpolate untrusted values into an inline script. Pass data via
JSON.stringify into a <script type="application/json"> block and read it with textContent, or set values from a same-origin fetch.
- Use
textContent and createElement for the feed instead of innerHTML, or escape every interpolated field.
- Consider a Content-Security-Policy header that disallows inline script.
Found in the 2026-08-16 audit (30-agent sweep, 481 findings). Every line reference was verified against main at the time of filing.
Two injection points.
Reflected,
backend/server.js:505: values from the OAuth callback are interpolated into an inline<script>without escaping, so a crafted callback URL executes attacker script on your origin, with access to the signed-in Firebase session.Stored,
dashboard.html:1116:spark.thumbnailandspark.idare interpolated intoinnerHTMLunescaped. Because any signed-in user can create a spark, one user can store script that runs in every other user's browser when the feed renders.Should be
JSON.stringifyinto a<script type="application/json">block and read it withtextContent, or set values from a same-origin fetch.textContentandcreateElementfor the feed instead ofinnerHTML, or escape every interpolated field.Found in the 2026-08-16 audit (30-agent sweep, 481 findings). Every line reference was verified against
mainat the time of filing.