Content Security Policy και CMP: πώς συνεργάζονται το CSP και η συναίνεση
Δύο επίπεδα ασφάλειας που πρέπει να συμφωνούν
Μια Content Security Policy (CSP) λέει στο πρόγραμμα περιήγησης από ποιες πηγές μπορεί μια σελίδα να φορτώνει scripts, στυλ, εικόνες, frames και αιτήματα δικτύου. Μια πλατφόρμα διαχείρισης συναίνεσης κάνει την αντίθετη δουλειά: αποφασίζει ποια από αυτά τα scripts επιτρέπεται να εκτελεστούν με βάση την επιλογή του χρήστη. Όταν τα δύο ρυθμίζονται ξεχωριστά, συγκρούονται. Το CMP αποτυγχάνει να φορτώσει επειδή το CSP το μπλοκάρει, ή το CSP χαλαρώνει τόσο πολύ για να φιλοξενήσει το CMP και τα ad tags ώστε δεν προστατεύει πια τίποτα.
Αυτός ο οδηγός εξηγεί ποιες οδηγίες CSP χρειάζεται συνήθως ένα CMP, πώς αλληλεπιδρούν τα nonces με την εισαγωγή scripts και πώς να κάνετε αλλαγές χωρίς να χαλάσετε το banner.
Τι χρειάζεται συνήθως ένα CMP από το CSP
Οι ακριβείς απαιτήσεις εξαρτώνται από τον προμηθευτή, επομένως ξεκινάτε πάντα από την τεκμηρίωση του δικού σας CMP. Γενικά, ελέγξτε αυτές τις οδηγίες:
script-src— το domain από το οποίο φορτώνεται το script του CMP, συν τυχόν πρόσθετα αρχεία script που φορτώνει.connect-src— τα endpoints που καλεί το CMP μεfetchή XHR, όπως διαμόρφωση, λίστα προμηθευτών, γεωγραφικός εντοπισμός και καταγραφή συναίνεσης.style-src— το domain του stylesheet, και πιθανώς inline στυλ αν το CMP εισάγει στοιχείο<style>ή ορίζει style attributes.img-src— λογότυπα, εικονίδια και τυχόν pixels χωρίς παρακολούθηση που χρησιμοποιεί το CMP.font-src— αν το banner φορτώνει δικές του γραμματοσειρές.frame-src— αν το CMP χρησιμοποιεί iframes, για παράδειγμα για κοινή χρήση συναίνεσης μεταξύ domains.
Σε ιστότοπους TCF, θυμηθείτε ότι το CMP δημιουργεί επίσης στη σελίδα ένα frame εντοπισμού με όνομα __tcfapiLocator. Αυτό το frame δημιουργείται χωρίς απομακρυσμένη πηγή, οπότε κανονικά δεν χρειάζεται εγγραφή στο frame-src, αλλά αξίζει να το επιβεβαιώσετε στις δοκιμές.
Το πρόβλημα του inline stub
Τα περισσότερα CMP σας ζητούν να τοποθετήσετε ένα μικρό inline script — το stub — στο head της σελίδας, ώστε άλλα scripts να βάζουν κλήσεις σε ουρά πριν φορτώσει το κύριο CMP. Μια αυστηρή CSP μπλοκάρει τα inline scripts εκτός αν τα επιτρέψετε ρητά. Έχετε τρεις επιλογές:
- Ένα nonce. Δημιουργήστε μια τυχαία τιμή ανά απάντηση, προσθέστε την στην κεφαλίδα CSP ως
'nonce-...'και στο<script>tag του stub. Είναι η πιο ευέλικτη επιλογή για δυναμικές σελίδες. - Ένα hash. Προσθέστε το hash SHA-256 των ακριβών περιεχομένων του stub στο
script-src. Λειτουργεί καλά για στατικούς ιστότοπους, αλλά κάθε αλλαγή στο stub, ακόμη και σε κενό διάστημα, το χαλάει. - Self-hosting του stub ως εξωτερικό αρχείο στο δικό σας domain, που καλύπτεται από το
'self'. Χρειάζεται προσοχή ώστε να φορτώνει αρκετά νωρίς.
Αποφύγετε το 'unsafe-inline' ως συντόμευση. Επιτρέπει κάθε inline script, κάτι που αφαιρεί μεγάλο μέρος της προστασίας που προσφέρει το CSP.
Nonces και scripts που εισάγει το CMP
Ένα CMP που μπλοκάρει scripts μέχρι να δοθεί συναίνεση συχνά λειτουργεί κρατώντας τα πίσω και εισάγοντάς τα αργότερα. Υπό μια CSP βασισμένη σε nonce, και αυτά τα εισαγόμενα scripts πρέπει να επιτρέπονται. Υπάρχουν δύο συνηθισμένες προσεγγίσεις:
- Μετάδοση nonce. Το CMP διαβάζει το nonce από το δικό του script tag και το προσθέτει σε κάθε script που εισάγει. Ελέγξτε αν το CMP σας το υποστηρίζει.
'strict-dynamic'. Αυτή η λέξη-κλειδί λέει στα προγράμματα περιήγησης που την υποστηρίζουν να εμπιστεύονται scripts που φορτώνονται από ένα ήδη έμπιστο script. Απλοποιεί τη ζωή με tag managers και CMP που εισάγουν scripts, αλλά σημαίνει επίσης ότι κάθε script που εμπιστεύεστε μπορεί να φορτώσει άλλα, επομένως εμπιστευτείτε προσεκτικά.
Οι tag managers θέτουν το ίδιο ζήτημα. Αν φορτώνετε ad και analytics tags μέσω tag manager, ακολουθήστε την τεκμηρίωσή του για τα nonces και βεβαιωθείτε ότι το CMP και ο tag manager χρησιμοποιούν συνεπή προσέγγιση.
Τα ad tags δυσκολεύουν το CSP
Η προγραμματική διαφήμιση φορτώνει scripts και frames από πολλά domains, και η λίστα αλλάζει όσο αλλάζουν οι συνεργάτες ζήτησης. Οι εκδότες συνήθως κάνουν μία από δύο επιλογές:
- Μια αυστηρή CSP σε σελίδες χωρίς προγραμματικές διαφημίσεις και μια ευρύτερη πολιτική όπου τρέχουν διαφημίσεις.
- Μια πολιτική εστιασμένη σε οδηγίες που παραμένουν διαχειρίσιμες, όπως
frame-ancestors,object-src 'none'καιbase-uri, ενώ οι πηγές scripts παραμένουν ευρύτερες.
Με όποιον τρόπο, το CMP πρέπει να βρίσκεται στη ρητή λίστα επιτρεπόμενων, όχι να καλύπτεται μόνο από wildcard, ώστε μια αλλαγή στο CSP να μην απενεργοποιεί αθόρυβα το banner.
Ανάπτυξη με λειτουργία Report-Only
Χρησιμοποιήστε πρώτα την κεφαλίδα Content-Security-Policy-Report-Only. Το πρόγραμμα περιήγησης αναφέρει παραβιάσεις χωρίς να μπλοκάρει τίποτα, ώστε να δείτε τι θα χαλούσε μια νέα πολιτική.
- Αναπτύξτε την πολιτική σε λειτουργία report-only με ένα endpoint αναφορών.
- Φορτώστε σελίδες σε καθαρά προφίλ προγράμματος περιήγησης και περάστε από ολόκληρη τη ροή συναίνεσης: πρώτη επίσκεψη, αποδοχή όλων, απόρριψη όλων, προσαρμοσμένη επιλογή, ανάκληση.
- Εξετάστε τις αναφορές παραβιάσεων και την κονσόλα του προγράμματος περιήγησης για μπλοκαρισμένους πόρους του CMP.
- Προσαρμόστε την πολιτική και μετά περάστε σε επιβολή.
- Διατηρήστε τις αναφορές ενεργές μετά την επιβολή για να εντοπίζετε οπισθοδρομήσεις.
Συμπτώματα σύγκρουσης με το CSP
- Το banner δεν εμφανίζεται ποτέ και η κονσόλα δείχνει παραβίαση CSP για το script του CMP.
- Το banner εμφανίζεται αλλά χωρίς στυλ, επειδή το
style-srcμπλοκάρει το CSS του. - Οι επιλογές δεν αποθηκεύονται, επειδή το
connect-srcμπλοκάρει την κλήση καταγραφής συναίνεσης. - Οι διαφημίσεις ή τα analytics δεν φορτώνουν ποτέ μετά τη συναίνεση, επειδή τα εισαγόμενα scripts δεν έχουν nonce.
- Το
__tcfapiείναι undefined, επειδή το inline stub μπλοκαρίστηκε.
Βασικά συμπεράσματα
- Ελέγξτε τα
script-src,connect-src,style-src,img-srcκαιframe-srcγια το CMP σας. - Επιτρέψτε το inline stub με nonce ή hash, όχι με
'unsafe-inline'. - Βεβαιωθείτε ότι τα scripts που εισάγονται μετά τη συναίνεση λαμβάνουν nonce ή καλύπτονται από το
'strict-dynamic'. - Δοκιμάστε κάθε διαδρομή συναίνεσης σε λειτουργία report-only πριν την επιβολή.
- Κρατήστε το CMP ρητά στη λίστα επιτρεπόμενων ώστε οι αλλαγές του CSP να μην μπορούν να το απενεργοποιήσουν.