11

Próbuję użyć MathJax jako części naszej aplikacji internetowej, która używa dość surowego Content Security Policy (CSP). Problem polega na tym, że MathJax jest kodowany do używania eval() [dokładniej, w postaci Function()], który nie jest domyślnie uważany za bezpieczny przez CSP.CSP: Jak zezwolić na niebezpieczne eval dla danego prefiksu URI (Firefox)

Używam następujący nagłówek CSP obecnie:

X-Content-Security-Policy: allow 'self'; img-src *; media-src *; frame-src *; font-src *; frame-ancestors 'none'; style-src *; report-uri '/:save-csp-violation'; 

co powoduje kod mathjax 2.0 niepowodzenie, ponieważ używa Function(). Próbowałem pozwolić na niebezpieczne-eval (tj. Function()) tylko dla MathJax zlokalizowanego w tym samym źródle poniżej ścieżki /:static/math/. Aby to zrobić, próbowałem dodać

unsafe-eval '/:static/math/*' 

aby pełny nagłówek wyglądać

X-Content-Security-Policy: allow 'self'; img-src *; media-src *; frame-src *; font-src *; frame-ancestors 'none'; style-src *; report-uri '/:save-csp-violation'; unsafe-eval '/:static/math/*' 

ale nadal nie mogę Firefox 13.0, aby uruchomić kod. Dostaję komunikat o błędzie Firefox Web Console (znajdujący się w menu Narzędzia - Web Developer):

[10:09:59.072] call to Function() blocked by CSP @ http://localhost:8080/:static/math/2.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML:29 

jednak nie otrzymuję raport CSP do „zgłosić-uri”. (Jak widzisz, obecnie test przeprowadzam przez niestandardowy port localhost bez SSL, w przypadku, który robi różnicę.) Przed dwukropkiem przed static nie jest literówką, rezerwuję wszystkie części ścieżki zaczynając od dwukropka do wewnętrznego użytku aplikacja, cała treść użytkownika może dowolnie definiować inne adresy URL.)

Czy moje użycie atrybutu unsafe-eval jest niepoprawne, czy też nie jest możliwe zezwolenie na niebezpieczne eval tylko dla podzbioru "self"? Celem jest zezwolenie na niebezpieczne eval tylko dla tego samego prefiksu ścieżki początkowej /:static/math, ścisłe wykonanie kodu CSS JS dla 'self' i bez kodu JS dla jakiejkolwiek innej metody.

Odpowiedz

13

Są tam kilka problemów: nagłówki

  1. CSP nie działają w ten sposób. CSP ma tylko ziarnistość pojedynczej kombinacji host + port (pochodzenie). Jeśli nie możesz pozwolić, aby jakikolwiek skrypt w twoim komputerze miał unsafe-eval, żaden skrypt nie może go mieć. Jedynym możliwym rozwiązaniem jest niestosowanie skryptu, który wymaga unsafe-eval (powodzenia w pisaniu samego MathJaxa).

  2. Składnia allow jest starą wersją Mozilli i nie należy jej używać. Bieżąca składnia to default-src, po której następuje nazwa schematu lub hosta lub miejsce pochodzenia, które są dozwolone jako źródło wszystkiego, a następnie zastępują domyślną wartość każdego typu podtypu (na przykład script-src) w zależności od potrzeb. Niektóre źródła mogą obsługiwać dodatkowe słowa kluczowe oprócz self. Na przykład script-src obsługuje unsafe-eval, co oznacza, że ​​każdy skrypt, który może wykonywać inne operacje, może uruchamiać eval() lub Function() i unsafe-inline, co oznacza, że ​​każdy element znacznika obsługujący pewien skrypt wbudowany może być wykonywany . Dopuszczenie wartości unsafe-eval może być dopuszczalne, ale unsafe-inline jest praktycznie bez zmian ze skryptem-src (w przeciwnym razie nie powinieneś w ogóle zajmować się CSP).

  3. Poprawna składnia script-src następująco:

    script-src 'self' 'unsafe-inline' 
    
  4. mathjax wykorzystuje również wbudowany styl atrybuty więc następuje potrzebne (chyba już dozwolone) lub mathjax trafi Exception s, starając się uczynić matematyki:

    style-src 'self' 'unsafe-inline' 
    

    nie jest możliwe stosowanie CSP, aby umożliwić JS wstawić atrybuty stylu i nie mają styl atrybuty już wstawiony w kodzie HTML, aby mieć wpływ.

  5. Wygląda na to, że Firefox 13.0 (przynajmniej) nie od razu "zadzwoni do domu" w przypadku naruszenia CSP. Większość raportów o naruszeniach zostaje przesłana po pewnym czasie od wydarzenia. Wygląda na to, że Chrome jest znacznie bardziej agresywny w przypadku przesyłania raportu, co sprawi, że testowanie będzie nieco łatwiejsze. Z mojego doświadczenia wynika, że ​​Firefox nie zawsze wysyła raport CSP - może używać heurystyki, aby nie wysyłać powtarzających się wiadomości.

Bonus: Aby obsługiwać webkit, należy powtórzyć konfigurację z nagłówkiem HTTP X-WebKit-CSP.

W końcu, aby uczynić pracę mathjax z Content-Security-Protection, czego potrzebujesz następujące nagłówki (zakładając, że masz dystrybucję bibliotekę mathjax przez siebie, a nie za pośrednictwem mathjax CDN):

X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; options eval-script 
X-WebKit-CSP: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 

Tutaj Atrybut options jest wymagany w Firefoksie 13.0 i mniejszej. Zgłosiłem problem z CSP MathJax pod numerem https://github.com/mathjax/MathJax/issues/256.

+1

Firefox 13.0 zawiera również błąd lub brakującą cechę, że jego nagłówek CSP nie pasuje do wariantu W3C. Zobacz błąd tutaj: https://bugzilla.mozilla.org/show_bug.cgi?id=746978 –

Powiązane problemy