Εν συντομία: Τα security headers είναι εντολές του διακομιστή ιστού προς το πρόγραμμα περιήγησης, που προστατεύουν τους επισκέπτες από επιθέσεις όπως το Cross-Site Scripting, το clickjacking και οι μη κρυπτογραφημένες συνδέσεις. Οι σημαντικότερες είναι οι HSTS, Content-Security-Policy, X-Content-Type-Options, προστασία από ξένα πλαίσια, Referrer-Policy και Permissions-Policy. Αποτελούν λογική θωράκιση, δεν αντικαθιστούν όμως τις ενημερώσεις στον διακομιστή.
Τι προσφέρουν τα security headers και τι όχι
Σε κάθε κλήση σελίδας ο διακομιστής ιστού στέλνει εκτός από το περιεχόμενο και κεφαλίδες. Ορισμένες από αυτές ελέγχουν λειτουργίες ασφαλείας του προγράμματος περιήγησης. Έτσι μπορεί π.χ. να οριστεί ότι μια σελίδα φορτώνεται μόνο μέσω HTTPS ή ότι το πρόγραμμα περιήγησης δεν εκτελεί scripts από ξένα domains.
Για τους διαχειριστές είναι σημαντική η τοποθέτηση: οι κεφαλίδες προστατεύουν πρωτίστως τους επισκέπτες, π.χ. από την υποκλοπή συνεδριών ή από παραποιημένες φόρμες. Δεν κλείνουν ευπάθειες στον διακομιστή. Μια αδυναμία στην PHP, στο CMS ή σε μια επέκταση παραμένει, όσο καλά και αν έχουν οριστεί οι κεφαλίδες. Σε συνδυασμό με καθαρό κώδικα περιορίζουν όμως σημαντικά τις συνέπειες πολλών σφαλμάτων.
Οι σημαντικότερες security headers συνοπτικά
| Κεφαλίδα | Σκοπός | Σύσταση ως αφετηρία |
|---|---|---|
| Strict-Transport-Security (HSTS) | επιβάλλει HTTPS για μελλοντικές κλήσεις | max-age=31536000; includeSubDomains |
| Content-Security-Policy (CSP) | ορίζει επιτρεπόμενες πηγές για scripts, εικόνες, πλαίσια | εξατομικευμένη, πρώτα ως Report-Only |
| X-Content-Type-Options | εμποδίζει το πρόγραμμα περιήγησης να μαντεύει τύπους αρχείων | nosniff |
| X-Frame-Options ή CSP frame-ancestors | εμποδίζει την ενσωμάτωση σε ξένες σελίδες (clickjacking) | SAMEORIGIN ή frame-ancestors 'self' |
| Referrer-Policy | περιορίζει ποια διεύθυνση διαβιβάζεται σε άλλες σελίδες | strict-origin-when-cross-origin |
| Permissions-Policy | απενεργοποιεί λειτουργίες του προγράμματος περιήγησης όπως κάμερα ή τοποθεσία | επιτρέψτε μόνο τις απαραίτητες λειτουργίες |
Το HSTS πρέπει να το ορίσετε μόνο όταν όλα τα subdomains είναι αξιόπιστα προσβάσιμα μέσω HTTPS. Το πρόγραμμα περιήγησης θυμάται την εντολή για το καθορισμένο χρονικό διάστημα· ένα σφάλμα δεν μπορεί τότε να ανακληθεί αμέσως. Ξεκινήστε ενδεχομένως με σύντομη διάρκεια και αυξήστε την μετά από επιτυχείς δοκιμές. Η πρόσθετη επιλογή preload καταχωρίζει το domain μόνιμα σε λίστες των κατασκευαστών προγραμμάτων περιήγησης και πρέπει να ορίζεται μόνο μετά από προσεκτικό έλεγχο.
Οι κεφαλίδες δεν είναι άλλωστε το μόνο σημείο όπου το πρόγραμμα περιήγησης προσφέρει προστασία. Τα cookies πρέπει να φέρουν τα χαρακτηριστικά Secure, HttpOnly και SameSite, ώστε οι συνεδρίες να μην υποκλέπτονται μέσω μη κρυπτογραφημένων συνδέσεων ή scripts. Πώς το ρυθμίζετε στην PHP, περιγράφει ο οδηγός για τα sessions.
Ρύθμιση security headers στο Nginx
Στο Nginx οι κεφαλίδες ανήκουν στο μπλοκ server του αντίστοιχου ιστότοπου. Η προσθήκη always φροντίζει ώστε να αποστέλλονται και στις σελίδες σφαλμάτων.
server {
# ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" always;
server_tokens off;
}
Μια ιδιομορφία του Nginx: αν ένα μπλοκ location ορίζει δικές του εντολές add_header, οι κεφαλίδες από το μπλοκ server δεν κληρονομούνται εκεί. Ελέγξτε γι' αυτό και τις υποσελίδες και τα στατικά αρχεία. Περαιτέρω θωράκιση για αυτόν τον συνδυασμό περιγράφει η σελίδα Ασφάλεια του Nginx με PHP-FPM.
Ρύθμιση security headers στον Apache
Στον Apache χρειάζεστε το module mod_headers. Οι εντολές ανήκουν στο VirtualHost ή, αν δεν υπάρχει πρόσβαση σε αυτό, στο .htaccess.
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
</IfModule>
ServerTokens Prod
ServerSignature Off
Τα ServerTokens και ServerSignature ανήκουν στην κύρια διαμόρφωση. Εμποδίζουν τον διακομιστή να αναφέρει την ακριβή έκδοσή του στις απαντήσεις και στις σελίδες σφαλμάτων. Στο php.ini πετυχαίνετε το ίδιο για την PHP με expose_php = Off.
Σταδιακή εισαγωγή της Content-Security-Policy
Η Content-Security-Policy είναι η πιο αποτελεσματική, αλλά και η πιο απαιτητική κεφαλίδα. Ορίζει από ποιες πηγές επιτρέπεται να φορτώνονται scripts, stylesheets, εικόνες, γραμματοσειρές και πλαίσια. Αν ένα script που έχει εισαχθεί κρυφά φορτωθεί από ξένο domain, το πρόγραμμα περιήγησης το μπλοκάρει.
Οι σύγχρονοι ιστότοποι ενσωματώνουν συχνά εργαλεία ανάλυσης, παρόχους πληρωμών, υπηρεσίες χαρτών ή βίντεο. Μια υπερβολικά αυστηρή πολιτική παραλύει τότε λειτουργίες. Προχωρήστε γι' αυτό σε στάδια:
- Ξεκινήστε πρώτα με
Content-Security-Policy-Report-Only. Το πρόγραμμα περιήγησης αναφέρει παραβάσεις στην κονσόλα προγραμματιστή ή σε μια διεύθυνση συλλογής, δεν μπλοκάρει όμως τίποτα. - Καταγράψτε όλες τις απαραίτητες πηγές και εγκρίνετε τες στοχευμένα, αντί να χρησιμοποιείτε γενικά placeholders.
- Μεταφέρετε σταδιακά τα inline scripts σε αρχεία ή εφοδιάστε τα με nonces, ώστε να αποφεύγεται το
'unsafe-inline'. - Μόνο μετά από μια φάση δοκιμών χωρίς απροσδόκητα μηνύματα, περάστε σε
Content-Security-Policy.
Η CSP συμπληρώνει το καθαρό escaping στον κώδικα, δεν το αντικαθιστά όμως. Πώς θωρακίζετε σωστά τις εξόδους στην PHP, αναφέρεται στον οδηγό Αποτροπή XSS στην PHP.
Έλεγχος των κεφαλίδων και αποφυγή τυπικών λαθών
Μετά από κάθε αλλαγή πρέπει να ελέγχετε αν οι κεφαλίδες φτάνουν πράγματι. Αυτό γίνεται χωρίς πρόσθετα εργαλεία με curl:
# Δοκιμή της διαμόρφωσης και επαναφόρτωση
nginx -t && systemctl reload nginx
# Εμφάνιση των κεφαλίδων της αρχικής σελίδας και ενός στατικού αρχείου
curl -sI https://www.example.de/ | grep -iE 'strict|content-security|x-content|x-frame|referrer|permissions|server'
curl -sI https://www.example.de/favicon.ico | grep -iE 'strict|x-content'
Τυπικά λάθη είναι οι διπλά ορισμένες κεφαλίδες, όταν ο διακομιστής ιστού και η εφαρμογή στέλνουν τις ίδιες κεφαλίδες, ένα CDN που βρίσκεται μπροστά και αφαιρεί ή αντικαθιστά κεφαλίδες, και κεφαλίδες που εμφανίζονται μόνο στην αρχική σελίδα, αλλά όχι στις ανακατευθύνσεις ή στις σελίδες σφαλμάτων. Ελέγξτε επιπλέον μετά από ενημερώσεις του CMS ή επεκτάσεων ασφαλείας αν έχουν αλλάξει οι κεφαλίδες.
Ορίστε γι' αυτό ένα σημείο όπου συντηρούνται οι κεφαλίδες, κατά προτίμηση ο διακομιστής ιστού ή η υπηρεσία που βρίσκεται μπροστά. Πολλές επεκτάσεις CMS προσφέρουν επίσης ρυθμίσεις για κεφαλίδες ασφαλείας. Αυτό είναι βολικό, οδηγεί όμως εύκολα σε διπλές ή αντιφατικές τιμές, αν ορίζει κεφαλίδες και ο διακομιστής. Για μεμονωμένες δοκιμές ταιριάζουν και τα εργαλεία προγραμματιστή του προγράμματος περιήγησης: στην καρτέλα δικτύου βλέπετε για κάθε αίτημα τις κεφαλίδες της απάντησης και η κονσόλα εμφανίζει παραβάσεις της Content-Security-Policy.
Πώς βοηθά συγκεκριμένα η PHP SOS;
- Ελέγχουμε τις τρέχουσες κεφαλίδες όλων των ιστοτόπων σας, ακόμη και πίσω από CDN και proxy, και επισημαίνουμε κενά και αντιφάσεις.
- Ορίζουμε τις κεφαλίδες κεντρικά στον διακομιστή ιστού στο πλαίσιο της θωράκισης διακομιστή και δοκιμάζουμε την αρχική σελίδα, τις υποσελίδες και τις σελίδες σφαλμάτων.
- Εισάγουμε τη Content-Security-Policy σε λειτουργία Report-Only, αναλύουμε τα μηνύματα και την ενεργοποιούμε μετά από συνεννόηση.
- Όπου οι αλλαγές κώδικα δεν είναι άμεσα δυνατές, συμπληρώνουμε την προστασία με κανόνες WAF και εικονικό patching.
Συχνές ερωτήσεις
Τι είναι τα security headers;
Τα security headers είναι πρόσθετα στοιχεία στην απάντηση του διακομιστή ιστού. Λένε στο πρόγραμμα περιήγησης, για παράδειγμα, ότι πρέπει να φορτώνει τη σελίδα μόνο μέσω HTTPS, να μην εκτελεί ξένα scripts ή να μην εμφανίζει τη σελίδα σε ξένα πλαίσια. Προστατεύουν κυρίως τους επισκέπτες.
Προστατεύουν τα security headers από το PHP2Shell;
Όχι. Το PHP2Shell είναι ευπάθεια της PHP στον διακομιστή, οι κεφαλίδες δρουν στο πρόγραμμα περιήγησης του επισκέπτη. Απέναντι στο PHP2Shell βοηθά η ενημέρωση σε διορθωμένη έκδοση PHP και η επανεκκίνηση όλων των workers. Οι κεφαλίδες αποτελούν συμπληρωματική θωράκιση για άλλα είδη επιθέσεων.
Μπορεί μια Content-Security-Policy να χαλάσει τον ιστότοπό μου;
Ναι, μια υπερβολικά αυστηρή πολιτική μπλοκάρει απαραίτητα scripts, γραμματοσειρές ή ενσωματωμένα περιεχόμενα. Γι' αυτό εισάγεται πρώτα σε λειτουργία Report-Only, αναλύονται τα μηνύματα και μόνο μετά ενεργοποιείται η επιβολή.
Έχει ακόμη νόημα το X-XSS-Protection;
Όχι. Τα τρέχοντα προγράμματα περιήγησης δεν αξιολογούν πλέον αυτή την κεφαλίδα και η σύσταση είναι να παραλείπεται ή να οριστεί σε 0. Προστασία από το Cross-Site Scripting προσφέρουν το καθαρό escaping στον κώδικα και μια Content-Security-Policy.