v0.27.0 - Krok 21 (runda 1+2): zabezpieczenie podstrony
v0.27.0 — Krok 21 (runda 1+2): zabezpieczenie podstrony /generator-faq
Pierwsze dwie rundy Kroku 21 (zakres podany przez usera: 26-sekcyjny brief
bezpieczenstwa podstrony generatora). Krok NIE jest zamkniety — pelny raport
i lista otwartych punktow: plany/KROK21-ZABEZPIECZENIE-PODSTRONY.md. Zero
zmian schematu bazy, zero usunietych plikow, zero nowych zaleznosci.
Brak jakichkolwiek naglowkow bezpieczenstwa — naprawione
/generator-faq (podstrona z shortcode'em, wewnatrz motywu klienta) i
/faqgenerator (trasa standalone, wlasny dokument) nie wysylaly ZADNEGO
naglowka bezpieczenstwa. Nowa klasa src/PublicUi/SecurityHeaders.php
rozpoznaje oba adresy i wysyla DWA rozne zestawy — bo maja zupelnie inny
poziom zaufania do reszty strony:
- standalone
/faqgenerator(w 100% nasz dokument, zero motywu, zero
cudzych skryptow) dostaje PELNE, restrykcyjne CSP:default-src 'self',
object-src 'none',base-uri 'self',form-action 'self',
connect-src 'self', plus nonce CSP zamiastunsafe-inlinew
script-src(token generowany raz na zadanie, ten sam co w atrybucie
nonce="…"trzech inline<script>, ktore ta trasa pisze) oraz
Cross-Origin-Opener-Policy/Cross-Origin-Resource-Policy: same-origin; - podstrona z shortcode'em wewnatrz motywu klienta dostaje TYLKO naglowki,
ktore NIC nie ograniczaja w ladowaniu zasobow (zeby nie zlamac motywu ani
innych wtyczek na tej samej stronie, ktorych ta wtyczka nie widzi):
X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin,
Permissions-Policy(geolocation/camera/microphone/payment/usb/interest-cohort
wylaczone),X-Frame-Options: SAMEORIGIN+ CSP zawezone do samego
frame-ancestors 'self'(ochrona przed clickjackingiem).
Caly zestaw przechodzi przez filtr aifaq_security_headers — furtka dla
wlasciciela, ktoremu ta polityka przeszkadza. Swiadomie pominiete:
Strict-Transport-Security — to odpowiedzialnosc serwera/CDN; blednie
ustawiony HSTS potrafi zablokowac wlascicielowi dostep do wlasnej strony.
Prompt injection z tresci strony (nie tylko z pytania goscia)
Fragmenty bazy wiedzy (kaskada zrodel z Kroku 17: post_content dowolnego
autora, postmeta/ACF, crawl wlasnych podstron) wchodzily do promptu SUROWE.
Ktokolwiek mogl wpisac w tresc strony wlasny naglowek ### ODPOWIEDZ: i
dopisac modelowi dowolne dalsze "instrukcje" w cudzym imieniu, albo
wstrzyknac wewnetrzny sentinel odmowy. src/Rag/Answerer.php neutralizuje
teraz TA SAMA regula (neutralize_structure()) zarowno pytanie goscia
(istniejace od poprzedniego audytu), jak i kazdy fragment kontekstu.
Przegladniete bez zmian kodu
Reszta 26-sekcyjnego briefu (uprawnienia shortcode/panelu, REST API,
XSS z odpowiedzi LLM, JSON-LD, klucz API, cache, automatyczne tworzenie
strony) — zweryfikowana czytaniem kodu: juz zamknieta przez audyt sprzed
K21 (v0.26.0). Tozsamosc podstrony (PageGuard) tez sprawdzona: "przejecie"
cudzej strony pod slugiem wymaga roli z prawem publikacji, wiec to nie jest
luka dla goscia — architektura (zamek + MAX_TRIES, audytowana w K18)
zostawiona bez zmian.
Odbior
php -l na wszystkich zmienionych/nowych plikach — czysto
tests/krok21-podstrona-security-test.php — 32/32 OK (nowy plik)
pelny runner (43 pliki tests/*.php) — 43/43 exit 0, zero regresji
budzet API: 0 — caly zestaw statyczny
Pozostale ryzyka — decyzje / do zrobienia
- CSP na stronie wewnatrz motywu klienta swiadomie nie ogranicza
script-src/style-src(dzieli dokument z cudzym kodem, ktorego nie
widzimy) — furtka: filtraifaq_security_headers. - Zero weryfikacji na zywej stronie w przegladarce (DevTools/securityheaders.com).
- Testy obciazeniowe/DoS na
/asknaleza juz do zakresu Kroku 22. - Multisite nie przetestowany na zywo w tej rundzie.
NASTEPNY KROK: dalsze rundy Kroku 21 (do ustalenia z userem) albo przejscie
do Kroku 22 — v1.0.0 (domkniecie, dawny "Krok 21" sprzed przenumerowania).