Skip to content

fix(pbn-queue): stored-XSS przy renderowaniu błędów PBN w kolejce#598

Merged
mpasternak merged 1 commit into
devfrom
fix/pbn-queue-xss
Jul 14, 2026
Merged

fix(pbn-queue): stored-XSS przy renderowaniu błędów PBN w kolejce#598
mpasternak merged 1 commit into
devfrom
fix/pbn-queue-xss

Conversation

@mpasternak

Copy link
Copy Markdown
Member

Problem (bezpieczeństwo)

Treść błędu pochodząca z PBN (niezaufana) trafiała do HTML bez escapowania w kilku miejscach kolejki eksportu:

  • format_pbn_error (templatetags/pbn_queue_extras.py) — ~10 surowych interpolacji (opis, details, endpoint, message, kod) przed mark_safe, używane w pbn_export_queue_table.html,
  • RenderHTMLWidget (admin.py) — renderuje TextField jako zaufany HTML,
  • pbn_export_queue_detail.htmlmsg.content|safe (×2) i komunikat|safe (×2) = surowe traceback z ciałem odpowiedzi PBN.

Payload w odpowiedzi PBN (np. </pre><script>alert(1)</script>) → stored-XSS w widoku kolejki.

Fix

  • escape() na wszystkich dynamicznych wartościach PBN w filtrze i widgecie,
  • usunięcie |safe z sinków treści PBN (Django auto-escapuje; tekst w <pre> renderuje się tak samo),
  • opis_bibliograficzny_cache|safe (zaufany, wyrenderowany HTML BPP) pozostaje.

Testy (TDD)

Repro w test_template_filters.py: fallback, description/details, prosty wyjątek, widget admina. Przed fixem 4 fail (payload przechodził), po fixie 7 passed (3 istniejące bez zmian).

Poza zakresem

Martwy pbn_api/admin/helpers.py:format_json (ta sama klasa problemu, ale zero konsumentów produkcyjnych) — zostawiony do D1 (toolkit admina), żeby ten PR trzymał się żywego wektora.

B0b z planu ekstrakcji PBN (#595).

🤖 Generated with Claude Code

…portu

Treść błędu z PBN (niezaufana) trafiała do HTML bez escapowania:
- filtr `format_pbn_error` interpolował ~10 wartości (opis, details, endpoint,
  message, kod) surowo przed `mark_safe`,
- widget `RenderHTMLWidget` w adminie kolejki renderował TextField jako HTML,
- szablon szczegółów renderował `msg.content|safe` i `komunikat|safe` (surowe
  traceback z ciałem odpowiedzi PBN).

Payload w odpowiedzi PBN (np. `</pre><script>…`) dawał stored-XSS w tabeli
i szczegółach kolejki. Fix: `escape()` na wszystkich dynamicznych wartościach
PBN w filtrze i widgecie, usunięcie `|safe` z sinków treści PBN (auto-escape).
`opis_bibliograficzny_cache|safe` (zaufany HTML BPP) pozostaje.

Testy: repro XSS (fallback, description/details, prosty wyjątek, widget) —
przed fixem 4 fail, po fixie 7 passed; istniejące testy filtra bez zmian.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mpasternak
mpasternak merged commit 645fa1d into dev Jul 14, 2026
24 checks passed
@mpasternak
mpasternak deleted the fix/pbn-queue-xss branch July 14, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant