Μετάβαση στο περιεχόμενο
leeveel
← Ευρετήριο
Nº 016 · · 6 λεπτά ανάγνωσης#security

Κάθε script στη σελίδα πληρωμής σου μπορεί να διαβάσει την κάρτα

Κάθε script σε μια σελίδα πληρωμής έχει την ίδια πρόσβαση με τον δικό σου κώδικα, και σε ό,τι πληκτρολογεί ο πελάτης. Η British Airways έχασε 20 εκατ. λίρες από είκοσι δύο γραμμές JavaScript. Το PCI DSS ζητά πλέον να ξέρεις κάθε script της σελίδας και να καταλαβαίνεις πότε αλλάζει ένα. Να τι σημαίνει αυτό — και πώς ξεκινάς σε ένα απόγευμα.

από Νεφέλη Κ.

++++

Μια σελίδα πληρωμής είναι ένα δωμάτιο όπου ο πελάτης λέει τον αριθμό της κάρτας του φωναχτά. Κάθε script της σελίδας είναι μέσα στο δωμάτιο. Ο κώδικας του checkout σου είναι εκεί. Το ίδιο και το SDK του παρόχου πληρωμών, ο tag manager, το chat widget που ζήτησε το support, το heat-map που ζήτησε το marketing, και ό,τι φορτώσει στη συνέχεια καθένα από αυτά. Ο browser δίνει σε όλα την ίδια πρόσβαση — στη φόρμα, στα πλήκτρα και στο δίκτυο. Φτιάξαμε το Roll Call, έναν δωρεάν έλεγχο που απαριθμεί ποιος βρίσκεται σε μια σελίδα πληρωμής, επειδή το «τι τρέχει στο checkout σου;» είναι η ερώτηση που κάνουμε πρώτη. Είναι και αυτή που οι λιγότερες ομάδες μπορούν να απαντήσουν από μνήμης. Να το σκεπτικό πίσω του, και η σειρά με την οποία θα δουλεύαμε.

Γιατί έχει σημασία ένα script στο checkout;

Επειδή ένα script tag δεν είναι επισκέπτης. Ό,τι φορτώνεται στη σελίδα τρέχει με τα δικαιώματα της ίδιας της σελίδας. Μπορεί να διαβάσει κάθε πεδίο, να ακούσει κάθε πάτημα πλήκτρου και να στείλει ό,τι ακούσει οπουδήποτε μπορεί να φτάσει ένα request. Το first-party ή third-party είναι ερώτηση για το ποιος μπορεί να αλλάξει το αρχείο, όχι για το τι μπορεί να κάνει το αρχείο. Αυτός είναι όλος ο μηχανισμός πίσω από το e-skimming, την οικογένεια επιθέσεων που συνήθως λέγεται Magecart. Το 2018 η British Airways σέρβιρε μια βιβλιοθήκη που ήδη χρησιμοποιούσε, τροποποιημένη με είκοσι δύο γραμμές JavaScript που αντέγραφαν τα στοιχεία της κάρτας όταν υποβαλλόταν η φόρμα. Το πρόστιμο του ICO έφτασε τα 20 εκατ. λίρες — λίγο κάτω από ένα εκατομμύριο τη γραμμή. Την ίδια χρονιά η σελίδα πληρωμής της Ticketmaster έπεσε θύμα skimming μέσα από ένα chat widget. Το 2024 το polyfill.io, ένα domain ενσωματωμένο σε πάνω από εκατό χιλιάδες sites, άλλαξε ιδιοκτήτη τον Φεβρουάριο και μέχρι τον Ιούνιο σέρβιρε κακόβουλο κώδικα. Κανείς δεν παραβίασε φόρμα κάρτας. Ήταν στη σελίδα, άρα ήταν στο δωμάτιο.

Τι ζητούν τα PCI DSS 6.4.3 και 11.6.1;

Η σελίδα παραπάνω είναι το πρόβλημα σε μία εικόνα. Το PCI DSS v4 απαντά με δύο απαιτήσεις που έγιναν υποχρεωτικές στις 31 Μαρτίου 2025. Η απαίτηση 6.4.3 ζητά απογραφή κάθε script σε μια σελίδα πληρωμής — καθένα εγκεκριμένο, καθένα με γραπτή επιχειρηματική αιτιολόγηση, καθένα με μια μέθοδο που διασφαλίζει την ακεραιότητά του. Η απαίτηση 11.6.1 ζητά έναν μηχανισμό που ανιχνεύει μη εξουσιοδοτημένες αλλαγές σε αυτά τα scripts και στα HTTP headers της σελίδας που επηρεάζουν την ασφάλεια, όπως τα λαμβάνει ο browser του πελάτη. Τουλάχιστον κάθε εβδομάδα, εκτός αν μια τεκμηριωμένη ανάλυση κινδύνου λέει αλλιώς. Μαζί, όπως τις διαβάζουμε εμείς: ξέρε τι τρέχει, μπόρεσε να πεις γιατί, κατάλαβε πότε αλλάζει. Καμία από τις δύο δεν κατονομάζει τεχνολογία. Η καθοδήγηση του Council προσφέρει το Content Security Policy και το Subresource Integrity ως παραδείγματα, όχι ως την απάντηση.

Η φόρμα κάρτας μας είναι στο iframe του παρόχου. Ισχύει και για εμάς;

Ναι — για τη σελίδα γύρω του, και αυτό είναι το κομμάτι για το οποίο μας ρωτούν πιο συχνά. Τα scripts μέσα στο iframe του παρόχου πληρωμών είναι ευθύνη του παρόχου. Τα scripts στη σελίδα που το ενσωματώνει είναι δικά σου, και αυτή είναι η σελίδα που κοιτάζει ο πελάτης. Ένα script στη σελίδα σου δεν μπορεί να διαβάσει μέσα στο iframe. Μπορεί όμως να το αντικαταστήσει, να το καλύψει με μια δική του φόρμα ή να αλλάξει πού στέλνει το κουμπί. Γι' αυτό το SAQ A, το συντομότερο ερωτηματολόγιο αυτοαξιολόγησης, άλλαξε τον Ιανουάριο του 2025. Οι απαιτήσεις 6.4.3 και 11.6.1 δεν είναι πια ξεχωριστές γραμμές· αντ' αυτού ο έμπορος επιβεβαιώνει, ως προϋπόθεση επιλεξιμότητας, ότι το site του δεν είναι ευάλωτο σε επιθέσεις μέσω scripts. Το FAQ 1588 του Council κατονομάζει τις τεχνικές αυτών των δύο απαιτήσεων ως έναν τρόπο να το δείξεις. Τα χαρτιά λιγόστεψαν. Η ερώτηση δεν πήγε πουθενά.

Τι μπαίνει στην απογραφή;

Η γραμμή παραπάνω είναι αυτό που θέλει το 6.4.3 για κάθε script, χωρισμένο ανάλογα με το ποιος μπορεί να το συμπληρώσει. Το αριστερό μισό είναι παρατηρήσιμο: το URL του script — ή το hash του, για ένα inline block — ο host και αν είναι δικός σου, και τι το φόρτωσε. Έπειτα ένα hash του αρχείου όπως είναι αυτή τη στιγμή, αν το tag έχει integrity attribute, και αν το επιτρέπει η πολιτική. Ο έλεγχός μας συμπληρώνει αυτό το μισό από το HTML όπως το λαμβάνει ένας browser, πριν τρέξει οτιδήποτε. Κατεβάζει έως σαράντα αρχεία script και υπολογίζει το hash του καθενός. Σημειώνει tag managers της Google, της Tealium, της Adobe και της Segment, επειδή προσθέτουν scripts που δεν μπορεί να δει, και απαριθμεί τα iframes. Το δεξί μισό είναι δικό σου, και κανένα εργαλείο δεν μπορεί να το συμπληρώσει: γιατί είναι εδώ το script, ποιος το έχει, ποιος το ενέκρινε, πώς θα καταλάβαινες ότι άλλαξε. Το CSV export έχει δύο από αυτές τις στήλες, την αιτιολόγηση και το ποιος το ενέκρινε, κενές για σένα. Η στήλη της αιτιολόγησης είναι εκεί που έχουμε δει απογραφές να γίνονται ειλικρινείς. Το chat widget και το heat-map σπάνια την επιβιώνουν, και η συντομότερη λίστα είναι ο ισχυρότερος έλεγχος.

Πώς αποδεικνύεις ότι ένα script δεν άλλαξε;

Με τρεις τρόπους, και ταιριάζουν σε διαφορετικά scripts. Το Subresource Integrity βάζει το hash του αρχείου μέσα στο tag, και ο browser αρνείται να τρέξει αρχείο που δεν ταιριάζει. Είναι σωστό για ένα αρχείο με έκδοση που δεν αλλάζει ποτέ. Είναι λάθος για ένα που ο πάροχος ενημερώνει επί τόπου, όπως τα περισσότερα SDK πληρωμών που έχουμε συναντήσει. Αποτυγχάνει και σιωπηλά: κανείς δεν ειδοποιείται, απλώς το checkout σταματά να δουλεύει, που είναι κι αυτό ένα είδος ειδοποίησης. Ένα Content Security Policy λέει ποιοι hosts μπορούν να σερβίρουν scripts στη σελίδα και πού μπορεί η σελίδα να στείλει δεδομένα. Μια πολιτική με 'unsafe-inline' ή με wildcard δεν λέει σχεδόν τίποτα, οπότε ξεκινάμε report-only, διαβάζουμε τις αναφορές και μετά την επιβάλλουμε. Η ανίχνευση αλλαγών είναι ο τρίτος: υπολόγισε το hash της σελίδας και κάθε script όπως τα παίρνει ο browser, σε πρόγραμμα, και ειδοποίησε στη διαφορά. Αυτό είναι που ζητά πραγματικά το 11.6.1. Ο έλεγχός μας δοκιμάζει το SRI απέναντι στο αρχείο που κατέβασε και δείχνει την τιμή integrity για αρχεία που θα μπορούσες να κλειδώσεις. Διαβάζει την πολιτική και απαριθμεί ποια scripts θα μπλόκαρε. Η σύγκριση δύο exports του δείχνει τι εμφανίστηκε, τι εξαφανίστηκε και τι άλλαξε — χειροκίνητος έλεγχος, όχι ο εβδομαδιαίος μηχανισμός.

Τι δεν μπορεί να δει ένας τέτοιος έλεγχος;

Αρκετά, και προτιμάμε να το πούμε εμείς παρά να το πει ένας assessor για εμάς. Διαβάζουμε τη σελίδα ως ανώνυμος επισκέπτης. Ένα checkout πίσω από login ή με άδειο καλάθι χρειάζεται ένα URL που φορτώνει χωρίς session, ή ένα αντίγραφο σε staging. Διαβάζουμε το HTML πριν τρέξει οτιδήποτε, οπότε τα scripts που εγχέει αργότερα ένας tag manager δεν είναι στη λίστα — στη σελίδα όμως είναι. Δεν ανοίγουμε το iframe του παρόχου. Βλέπουμε τα cookies που θέτει ο server, όχι αυτά που θέτουν τα scripts. Και δεν μπορούμε να σου πούμε αν είσαι compliant, επειδή κανένα εργαλείο δεν μπορεί. Αυτό επικυρώνεται στα έντυπα του Council, μέσω του acquirer σου ή ενός Qualified Security Assessor. Δεν υπάρχει PCI-certified έλεγχος scripts, ούτε ο δικός μας. Γράψαμε την ίδια προειδοποίηση για τις αναφορές scan: το εργαλείο βρίσκει αυτό που του είπαν να βρει, και η δουλειά είναι το κομμάτι που δεν μπορεί.

Από πού ξεκινάς, λοιπόν;

Με αυτή τη σειρά. Ένα: τρέξε το roll call στο URL του checkout και κατέβασε το CSV. Αυτό είναι το απόγευμα. Δύο: συμπλήρωσε το δεξί μισό κάθε γραμμής και διάγραψε ό,τι δεν μπορεί να δικαιολογήσει τη θέση του σε σελίδα πληρωμής. Η απάντηση στο marketing είναι συνήθως μια άλλη σελίδα. Τρία: κλείδωσε με SRI ό,τι έχει έκδοση και αστυνόμευσε τα πάντα με ένα CSP, πρώτα report-only. Τέσσερα: κράτα τους tag managers έξω από τη σελίδα πληρωμής, όπως κάνουμε εμείς, ή βάλε ό,τι φορτώνουν στην απογραφή και υπό έλεγχο αλλαγών. Πέντε: αποφάσισε ποιος το ελέγχει κάθε εβδομάδα και πώς ειδοποιείται. Ένα diff ανάμεσα σε δύο exports είναι μια χαρά για μια Τρίτη· ένας μηχανισμός είναι αυτό που χρειάζεσαι για έναν χρόνο. Έξι: πήγαινε τη λίστα σε όποιον υπογράφει την αξιολόγησή σου πριν σου τη ζητήσει. Αν το βήμα πέντε είναι αυτό για το οποίο δεν έχεις άνθρωπο, αυτό είναι το κομμάτι που κάνουμε εμείς.

Τι άλλαξε από τότε που αρχίσαμε να το λέμε φωναχτά: η σελίδα πληρωμής έπαψε να είναι η σελίδα που δεν αγγίζει κανείς. Ποτέ δεν ήταν. Ήταν η σελίδα που άγγιζαν όλοι — το support με ένα widget, το marketing με ένα pixel, ένας developer με ένα polyfill το 2019 — και κανείς δεν κρατούσε τη λίστα. Η απογραφή μετατρέπει έναν αόριστο φόβο σε μια σύντομη συζήτηση για το ποιος επιτρέπεται να είναι στο δωμάτιο. Η απαίτηση 6.4.3 είναι ο λόγος που επιτρέπεται να πεις όχι. Το roll call είναι ο τρόπος να μάθεις σε ποιον να το πεις.