Zalecenia HSTS w .htaccess

Oct 18 2020

Zobacz mój poprzedni post w poniższym hiperłączu

Zaktualizowałem mój .htaccessplik, aby uwzględnić HSTS, wraz z wieloma zalecanymi zmianami. Zobacz fragment poniżej. Chciałbym podkreślić, że implementacja HSTS nie może być lekceważona dla nikogo nowego. Mając to na uwadze, szukam porady, co można zrobić inaczej niż ci, którzy mają wiedzę na temat .htaccess.

#IMPLEMENT HSTS
<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</IfModule>

#CUSTOM ERROR PAGES
ErrorDocument 400 /allerror.php
ErrorDocument 401 /allerror.php
ErrorDocument 403 /allerror.php
ErrorDocument 404 /allerror.php
ErrorDocument 405 /allerror.php
ErrorDocument 408 /allerror.php
ErrorDocument 500 /allerror.php
ErrorDocument 502 /allerror.php
ErrorDocument 504 /allerror.php

RewriteEngine On

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] #FORCE WWW TO NON-WWW RewriteCond %{HTTP_HOST} ^www.example.com [NC] RewriteRule ^(.*)$ https://example.com/$1 [L,R=301] #URL EXTENSION REMOVAL RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC] RewriteRule ^ /%1 [NC,L,R] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^ %{REQUEST_URI}.html [NC,L] #HOTLINKING PROTECTION RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com(/.*)*$ [NC]
RewriteCond %{HTTP_REFERER} !^$ RewriteRule \.(css|flv|gif|ico|jpe|jpeg|jpg|js|mp3|mp4|php|png|pdf|swf|txt)$ - [F]

#CONTENT SECURITY POLICY
<FilesMatch "\.(html|php)$"> Header set Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: 'unsafe-inline'; media-src 'self' data: 'unsafe-inline'; connect-src 'self';" </FilesMatch> #REDIRECT FOR DATE PAGE RewriteRule ^date$ /storage/date-202010 [R=301,L]

#REDIRECT FOR HOME PAGE
RewriteRule ^home$ / [R=301,L] #PREVENT DIRECTORY BROWSING Options All -Indexes #FILE CACHING #cache html and htm files for one day <FilesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>
    #cache css, javascript and text files for one week
<FilesMatch "\.(js|css|txt)$"> Header set Cache-Control "max-age=604800" </FilesMatch> #cache flash and images for one month <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|mp4|png)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
    #disable cache for script files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$"> Header unset Cache-Control </FilesMatch> #BLOCKS FILE TYPES FOR USERS <FilesMatch "\.(ht[ap]|ini|log|sh|inc|bak)$">
Require all denied
</FilesMatch>

Implementacja HSTS

Aby zwrócić uwagę na kilka rzeczy, których nauczyłem się podczas badania HSTS:

  1. Wymagany jest certyfikat SSL
  2. Jeśli Twoje witryny są dostępne przez HTTP, przekieruj wszystkie żądania do HTTPS za pomocą stałego przekierowania 301.
  3. Zawierać następujące elementy w .htaccesspliku: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. Maksymalny wiek musi wynosić co najmniej 10886400 sekund lub 18 tygodni. Idź na dwuletnią wartość.
  4. Dodaj swoją domenę do listy wstępnego ładowania, korzystając z pierwszego linku poniżej.

Zachęcam wszystkich do przeczytania każdego źródła poniżej, aby uzyskać więcej informacji.

  • Przesyłanie listy wstępnego ładowania HSTS
  • Co to jest HSTS i dlaczego powinienem go używać? | Acunetix
  • Co to jest HSTS i czy powinienem go wdrożyć? | Dynamika sieci
  • Dlaczego strony internetowe powinny używać HSTS do poprawy bezpieczeństwa i SEO

Odpowiedzi

3 MrWhite Oct 27 2020 at 23:09

Istnieją dwa aspekty zabezpieczeń HTTP Strict Transport Security (HSTS):

  1. Wdrażanie HSTS w Twojej witrynie.
  2. Przesyłanie Twojej witryny już obsługującej HSTS do listy wstępnego ładowania HSTS . W tym miejscu „lista witryn HSTS” jest kompilowana bezpośrednio w przeglądarce, co pozwala uniknąć pierwszego żądania przesłanego przez HTTP (gdzie żądanie jest potencjalnie podatne na ataki MITM).

Wydaje się, że idziesz prosto na # 2. Nie jest to koniecznie zalecane. Potraktuj „listę wstępnego załadowania” jako podróż w jedną stronę. Technicznie możliwe jest usunięcie z listy wstępnego ładowania; realistycznie, to nie jest coś, o czym chciałbyś nawet myśleć. (To trudne - wolne - wystarczy cofnąć się od samego HSTS.)

Sama strona przesyłania listy wstępnego ładowania nie zaleca przechodzenia od razu do „przesyłania listy wstępnego ładowania”. Zaleca się zwiększenie tego max-ageparametru przez pewien czas (miesiące), przed wykonaniem ostatniego kroku w celu przesłania do listy wstępnego ładowania. Testuj testy testowe w międzyczasie, aby upewnić się, że certyfikaty SSL są niezawodnie odnawiane, brak ostrzeżeń o mieszanej zawartości itp.

Byłbym również ostrożny, jeśli chodzi o przesyłanie listy wstępnego ładowania HSTS (lub nawet w pewnym stopniu samego HSTS) na serwerze współdzielonym , gdzie nie masz pełnej kontroli nad konfiguracją SSL. W rzeczywistości nie określasz, czy jesteś na serwerze współdzielonym, czy nie, ale ponieważ robisz całą tę konfigurację .htaccess, zakładam, że tak. Jeśli masz własny serwer i dostęp do konfiguracji serwera, większość tego powinna być skonfigurowana w konfiguracji server / virtualhost (i jest to prawdopodobnie łatwiejsze i bardziej niezawodne).

Pamiętaj, że po przejściu przez trasę HSTS (a użytkownicy uzyskali dostęp do witryny HTTPS lub znajdujesz się na „liście wstępnego ładowania”), dostęp do Twojej witryny będzie możliwy tylko przez HTTPS. Dotyczy to nie tylko Twojej witryny, ale także wszelkich usług stron trzecich, z których możesz korzystać (ostrzeżenia przeglądarki o mieszanej zawartości itp.).

#IMPLEMENT HSTS
<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</IfModule>

To ustawia wymagany nagłówek odpowiedzi HTTP HSTS dla „większości” * 1 odpowiedzi (ale zwróć uwagę na preloadparametr, który prawdopodobnie powinien być początkowo pominięty).

* 1 Jednak ta dyrektywa niekoniecznie ustawia wymagany nagłówek we wszystkich odpowiedziach. Wymaganiem HSTS jest również ustawienie nagłówka w odpowiedziach „przekierowujących” (np. Z www na inną niż www w HTTPS). Obecnie powyższe nie robi tego. Trzeba mieć przy użyciualways stan naHeaderdyrektywie, aby ustawić nagłówek na odpowiedzi innych niż 200 OK. Na przykład:

# Use "always" condition to set on "redirects" as well.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

(Na razie usunąłem również preloadparametr).

Nie potrzebujesz <IfModule>opakowania i należy je usunąć. mod_headers powinno być domyślnie włączone. To jest twój serwer, wiesz, czy mod_headers jest włączony czy nie. Aby to działało, należy włączyć mod_headers . Nie chcesz, aby to cicho zawiodło, jeśli mod_headers nie będą dostępne - potrzebujesz powiadomienia, gdy tylko się to nie powiedzie z błędem w dziennikach.

W wielu artykułach stwierdza się, że nagłówek należy ustawiać tylkoStrict-Transport-Security w bezpiecznych odpowiedziach (HTTPS). A „przesłanie listy wstępnego ładowania” rzeczywiście powoduje „ostrzeżenie” (nie jest to ściśle „błąd”, jak sądzę), jeśli również wyślesz nagłówek przez HTTP. Jednak, mimo że musi być ustawiony tylko na odpowiedź HTTPS, zgodne przeglądarki ignorują ten nagłówek, gdy jest wysyłany przez niezaszyfrowane połączenie HTTP (aby zapobiec atakom MITM), więc nie powinno mieć znaczenia, czy nagłówek jest również „niepotrzebnie” przesyłany przez HTTP. Byłoby to łatwiejsze do zarządzania w odpowiednich <VirtualHost>kontenerach w konfiguracji serwera głównego. Wysyłanie tego nagłówka tylko w odpowiedziach HTTPS w programie .htaccessjest bardziej złożone (i przez to bardziej podatne na błędy). Konieczne byłoby zastosowanie dodatkowej zmiennej środowiskowej, której można użyć do warunkowego ustawienia nagłówka odpowiedzi HSTS.

Na przykład:

# Set environment var "HSTS" if accessed over HTTPS connection
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=HSTS:1]

# Conditionally set only on HTTPS connections (ie. when "HSTS" env var is set)
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" env=HSTS

W przeciwnym razie uważam, że pozostałe dyrektywy są w porządku w odniesieniu do HSTS. Ale jak zawsze, test testowy test.


Rozwiąż wiele (niepotrzebnych) przekierowań

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]

Potencjalnym problemem w tym przypadku (w przypadku drugiego i trzeciego przekierowania kanonicznego powyżej, po przekierowaniu HTTP do HTTPS) jest to, że potencjalnie skutkuje to dwoma dodatkowymi przekierowaniami, jeśli zażądano www+ .html. Można to rozwiązać, po prostu odwracając te dwa przekierowania i włączając kanoniczną nazwę hosta do przekierowania „USUWANIE ROZSZERZENIA URL-a” (jak wspomniałem w mojej odpowiedzi na Twoje wcześniejsze pytanie ).

Na przykład:

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ https://example.com/%1 [R=301,L]

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [R=301,L]

Zobacz moją poprzednią odpowiedź na alternatywne podejście do przekierowania „USUWANIE ROZSZERZENIA URL-a”, które rozwiązuje niektóre potencjalne problemy.

Jeśli nie używasz wwwsubdomeny na innych nazwach hostów (np. www.subdomain.example.com), Możesz uprościć CondPattern na www do przekierowania innego niż www, aby po prostu ^www\., tj. jakakolwiek żądana nazwa hosta, która po prostu się uruchamia www., zamiast sprawdzania całej nazwy hosta.


Dodatkowe poprawki

Pętla usuwania / ponownego zapisywania rozszerzenia adresu URL (błąd wewnętrzny serwera 500)

Jest jeszcze kilka innych kwestii, których nie omawiałem we wcześniejszym pytaniu , niezwiązanych z HSTS, które omówię poniżej ...

#URL EXTENSION REMOVAL
:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [NC,L]

Ten (i podobny) jest jednym z tych fragmentów kodu, które są „na ślepo” kopiowane / wklejane wszędzie (i mam na myśli wszędzie ) jako „standardowy” sposób dodawania (przepisywania adresu URL) rozszerzenia pliku podczas korzystania z adresów URL bez rozszerzeń. Jednak, chociaż prawdopodobnie „działa” z Twoimi prawidłowymi adresami URL, ma poważną wadę podczas żądania nieprawidłowych adresów URL ...

Jeśli /about.htmljest to prawidłowy plik, który chcesz udostępnić podczas żądania adresu URL bez rozszerzenia, /aboutto działa poprawnie . Jeśli jednak zażądam (złośliwie) zażądam /about/lub /about/<anything>wyśle ​​serwer do spiralnej pętli przepisywania, co spowoduje odpowiedź 500 Internal Server Error. Użytkownik końcowy nie powinien mieć możliwości wywołania takiej odpowiedzi (potencjalnie bardziej podatny na ataki DDOS i inne wrogie zachowania).

Dzieje się tak, ponieważ REQUEST_FILENAME(ścieżka zamapowanego systemu plików) niekoniecznie odnosi się do tej samej publicznej ścieżki REQUEST_URIURL, co zmienna (żądana ścieżka URL).

Aby rozwiązać ten problem, używaj REQUEST_URIprzez cały czas. Na przykład:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^ %{REQUEST_URI}.html [L]

( NCFlaga jest tutaj zbędna w RewriteRuledyrektywie).

Zobacz moją odpowiedź do następnego ServerFault pytanie , aby uzyskać więcej szczegółów na ten temat.

Ochrona Hotlink - uproszczenie stanu

#HOTLINKING PROTECTION
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com(/.*)*$ [NC]

Jest to stosunkowo niewielkie. Wyrażenie regularne w powyższym warunku można uprościć. W tym momencie w .htaccesspliku (www\.)?nazwa hosta została już kanonizowana w celu usunięcia www z subdomeny, więc podwzór w powyższym jest zbędny. Podobnie jak końcowy (/.*)*$podwzór, który po prostu pasuje do wszystkiego innego. Nie musisz tutaj niczego dopasowywać , wystarczy zapewnić, że Referernagłówek zaczyna się od odpowiedniej (schemat +) nazwy hosta.

Na przykład:

RewriteCond %{HTTP_REFERER} !^https://example\.com

NCFlaga jest także tutaj zbędny. Wymuszanie dopasowania bez rozróżniania wielkości liter, gdy nie jest to wymagane, po prostu tworzy (odrobinę) więcej pracy dla twojego serwera, aw niektórych przypadkach może otworzyć cię na luki w zabezpieczeniach („zduplikowana zawartość” jest powszechna - chociaż nie stanowi to problemu) .

Włączanie niepotrzebne Options

#PREVENT DIRECTORY BROWSING
Options All -Indexes

To nie tylko zapobiega „przeglądaniu katalogów”. AllArgumentem umożliwia kilka innych rzeczy, które prawdopodobnie nie potrzeba, jak po stronie serwera zawiera ( Includes) oraz możliwość wykonywania skryptów CGI ( ExecCGI). (Nawiasem mówiąc, jest to jedyny przypadek, kiedy można mieszać argumenty z a +lub -bez.) Aby tylko zapobiec przeglądaniu katalogów (tj. Automatycznemu generowaniu indeksów katalogów przez mod_autoindex), usuń Allargument.

Jednak prawdopodobnie potrzebujesz tylko FollowSymLinks(co może być już ustawione w konfiguracji serwera), więc możesz zamiast tego ustawić następujące:

Options FollowSymLinks

Zwróć uwagę na brak +lub -. To tylko ustawia FollowSymLinks, więc wyłączanie Indexes("przeglądanie katalogów"), jeśli było już ustawione.