Τρέχουσα κατάσταση: PHP2Shell. Δύο κρίσιμες ευπάθειες της PHP (CVSS 9.2) επιτρέπουν κακόβουλο κώδικα χωρίς σύνδεση. Patches από τις 21/10/2026.Τι πρέπει να γίνει τώρα →

Δημόσιος φάκελος .git: μια υποτιμημένη διαρροή δεδομένων

Γιατί ένα webroot που ανεβαίνει με Git μπορεί να αποκαλύψει ολόκληρο τον πηγαίο κώδικα μαζί με το ιστορικό, πώς το ελέγχετε, το αποκλείετε άμεσα και στήνετε μόνιμα το deployment χωρίς φάκελο .git.

Ημερομηνία 6 λεπτά ανάγνωσηςΑσφαλής ανάπτυξη

Εν ολίγοις: Ένας δημόσιος φάκελος .git προκύπτει όταν ένας ιστότοπος ανεβαίνει με git clone ή git pull απευθείας στο webroot και ο διακομιστής ιστού δεν αποκλείει κρυφούς φακέλους. Τότε μπορεί να ανακτηθεί ολόκληρος ο πηγαίος κώδικας μαζί με το ιστορικό εκδόσεων, συμπεριλαμβανομένων στοιχείων πρόσβασης που είχαν γίνει νωρίτερα check-in. Ελέγξτε τα domains σας με μια απλή κλήση, αποκλείστε αμέσως την πρόσβαση, αλλάξτε το deployment σε πακέτα χωρίς .git και αντικαταστήστε τα στοιχεία πρόσβασης από το ιστορικό.

Ο πηγαίος κώδικας για όποιον τον θέλει

Το Git είναι το βασικό εργαλείο ελέγχου εκδόσεων και για μικρές ομάδες είναι φυσικό να χρησιμοποιείται και για την ανάπτυξη στην παραγωγή: σύνδεση στον διακομιστή, git pull, τελείωσε. Λειτουργεί αξιόπιστα και είναι γρήγορο. Έχει όμως μια παρενέργεια που συχνά κανείς δεν προσέχει.

Στον φάκελο του έργου υπάρχει ένας κρυφός φάκελος .git. Περιέχει όχι μόνο την τρέχουσα κατάσταση, αλλά κάθε αρχείο σε κάθε έκδοση που έγινε ποτέ check-in, μαζί με μηνύματα commit, ονόματα και διευθύνσεις email των προγραμματιστών και αναφορές σε διακομιστές. Αν αυτός ο φάκελος βρίσκεται στο webroot και ο διακομιστής ιστού τον παραδίδει, μπορεί να τον ανακτήσει ο καθένας.

Για τους επιτιθέμενους αυτό είναι δώρο. Με τον πηγαίο κώδικα οι αδυναμίες αναζητούνται στοχευμένα, αντί να μαντεύονται απ' έξω. Και στο ιστορικό βρίσκονται συχνά πράγματα που φαινόταν να έχουν διαγραφεί προ πολλού: ένας κωδικός βάσης δεδομένων από τα πρώτα χρόνια, ένα κλειδί API, ένα αρχείο δοκιμής με δεδομένα πελατών.

Είναι δημόσιος ο φάκελος .git; Έτσι το ελέγχετε

Ο έλεγχος διαρκεί δευτερόλεπτα και δεν αλλάζει τίποτα. Καλέστε για κάθε domain και υποτομέα ένα αρχείο που υπάρχει σε κάθε αποθετήριο Git:

# Αναμενόμενο: 403 ή 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/config
# Στον διακομιστή: Υπάρχουν φάκελοι .git κάτω από τα webroots;
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null

Μια κατάσταση 200 σημαίνει: ο φάκελος είναι προσβάσιμος. Προσέξτε και τους υποφακέλους. Μερικές φορές το αποθετήριο δεν βρίσκεται στο ίδιο το webroot, αλλά σε έναν φάκελο πρόσθετου ή θέματος που συντηρείται χωριστά με Git.

Ελέγξτε επιπλέον τα περιβάλλοντα staging και δοκιμών. Ενημερώνονται συχνότερα με Git απ' ό,τι η παραγωγή και είναι συχνά προσβάσιμα σε υποτομείς που μαντεύονται εύκολα.

Άμεσα: αποκλεισμός της πρόσβασης

Μέχρι να αλλάξει το deployment, ένας κανόνας στον διακομιστή ιστού αποκλείει την πρόσβαση σε φακέλους ελέγχου εκδόσεων. Ένας γενικός αποκλεισμός για κρυφά αρχεία, όπως περιγράφεται στο Σωστή προστασία στοιχείων πρόσβασης και αρχείων .env, το καλύπτει επίσης. Όποιος θέλει να αποκλείσει στοχευμένα μόνο τον έλεγχο εκδόσεων, χρησιμοποιεί έναν στενότερο κανόνα:

location ~ /\.(git|svn|hg)(/|$) {
    return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)

Έπειτα επαναλάβετε τον παραπάνω έλεγχο, και μάλιστα με πραγματική κλήση από έξω: ένας επιτυχής έλεγχος διαμόρφωσης λέει μόνο ότι η σύνταξη είναι σωστή, όχι ότι ο κανόνας ισχύει πριν από άλλους κανόνες για στατικά αρχεία. Σε πάνελ όπως το Plesk ή το cPanel καταχωρίστε τον κανόνα στις προβλεπόμενες πρόσθετες οδηγίες, ώστε να μη χαθεί στην επόμενη δημιουργία της διαμόρφωσης.

Δράστε άμεσα

Αν ο φάκελος ήταν προσβάσιμος, αντιμετωπίστε όλα τα στοιχεία πρόσβασης που βρέθηκαν ποτέ στο αποθετήριο ως γνωστά. Ο αποκλεισμός από μόνος του δεν αρκεί τότε, οι τιμές πρέπει να αντικατασταθούν.

Μόνιμα: ανάπτυξη χωρίς .git στο webroot

Ο αποκλεισμός είναι μια ασφάλιση και όχι λύση. Μόνιμα ο έλεγχος εκδόσεων δεν ανήκει στον παραγωγικό διακομιστή. Δοκιμασμένοι δρόμοι, ανάλογα με το περιβάλλον σας:

Μέθοδος Πώς λειτουργεί Κατάλληλη για
Πακέτο build από το CI Το pipeline χτίζει ένα αρχείο χωρίς .git, ο διακομιστής το αποσυμπιέζει σε έναν νέο φάκελο release Ομάδες με CI/CD
git archive δημιουργεί ένα αρχείο μιας κατάστασης χωρίς δεδομένα εκδόσεων μικρά έργα χωρίς pipeline
rsync με εξαιρέσεις μεταφέρει μόνο τα απαραίτητα αρχεία κλασικοί διακομιστές
Εικόνα container Ο κώδικας αντιγράφεται στην εικόνα κατά το build, το .git αποκλείεται μέσω .dockerignore Λειτουργία με containers

Ένας φάκελος release ανά έκδοση με συμβολικό σύνδεσμο προς την τρέχουσα κατάσταση έχει ένα ακόμη πλεονέκτημα: σε περίπτωση προβλήματος μπορείτε να γυρίσετε αμέσως πίσω. Για περιβάλλοντα με containers, το CI/CD: αυτόματη ανακατασκευή εικόνων PHP περιγράφει πώς γίνονται αναπαραγώγιμα τα builds. Εκεί πρέπει να ελέγχεται και ότι το .git δεν καταλήγει στην εικόνα.

# Παράδειγμα: δημιουργία πακέτου μιας κατάστασης χωρίς δεδομένα εκδόσεων
git archive --format=tar.gz -o release.tar.gz HEAD

Άλλα αρχεία του έργου που δεν ανήκουν στο webroot

Ο φάκελος .git είναι το πιο γνωστό παράδειγμα, αλλά όχι το μοναδικό. Όποιος ανεβάζει ολόκληρους φακέλους έργου, φέρνει στο webroot και άλλα αρχεία που δεν έχουν καμία δουλειά εκεί:

  • Φάκελοι περιβαλλόντων ανάπτυξης όπως το .idea ή το .vscode, όπου επεκτάσεις για το ανέβασμα αρχείων αποθηκεύουν ενίοτε διευθύνσεις διακομιστών και στοιχεία πρόσβασης.
  • composer.json και composer.lock, που αποκαλύπτουν τις ακριβείς εκδόσεις όλων των βιβλιοθηκών και διευκολύνουν έτσι την αναζήτηση γνωστών ευπαθειών.
  • Διαμορφώσεις για δοκιμές, εργαλεία build και pipelines, που αποκαλύπτουν εσωτερικά hostnames και διαδικασίες.
  • Κατάλοιπα λειτουργικών συστημάτων όπως το .DS_Store, που περιέχουν λίστες αρχείων ολόκληρων φακέλων.

Η λύση είναι η ίδια όπως για τον φάκελο .git: να παραδίδεται μόνο ό,τι πρέπει να είναι δημόσιο, ιδανικά μέσω ξεχωριστού υποφακέλου ως webroot. Όποιος αλλάζει ούτως ή άλλως το deployment σε πακέτα, ορίζει ταυτόχρονα μια λίστα αποκλεισμένων αρχείων και την ελέγχει σε κάθε νέο εργαλείο του έργου.

Αν ο φάκελος ήταν ανοιχτός: έλεγχος ιστορικού και αρχείων καταγραφής

Αν αποδειχθεί ότι ο φάκελος .git ήταν προσβάσιμος, προχωρήστε με αυτή τη σειρά:

  1. Αποκλείστε την πρόσβαση και επαναλάβετε τον έλεγχο.
  2. Ψάξτε το ιστορικό για το ποια μυστικά έγιναν ποτέ check-in: αρχεία διαμόρφωσης, .env, κλειδιά, dumps βάσεων δεδομένων.
  3. Αντικαταστήστε τα στοιχεία πρόσβασης, και μάλιστα όλα όσα βρέθηκαν στο βήμα 2, ακόμη κι αν δεν υπάρχουν πια στον κώδικα.
  4. Αξιολογήστε τα αρχεία καταγραφής πρόσβασης για το αν ανακτήθηκαν αρχεία κάτω από το /.git/ με κατάσταση 200 και από ποιες διευθύνσεις. Πώς γίνεται, δείχνει το Ανάλυση των αρχείων καταγραφής του διακομιστή ιστού μετά από επίθεση.
  5. Ελέγξτε στοχευμένα τον πηγαίο κώδικα, γιατί οι επιτιθέμενοι τον γνωρίζουν πλέον. Οι γνωστές αδυναμίες πρέπει να διορθωθούν κατά προτεραιότητα.
  6. Διευκρινίστε το θέμα προστασίας δεδομένων, αν στο ιστορικό υπήρχαν προσωπικά δεδομένα, για παράδειγμα εξαγωγές δοκιμών. Την αξιολόγηση αναλαμβάνει ο υπεύθυνος προστασίας δεδομένων σας.

Εργαλεία αναζήτησης μυστικών σε αποθετήρια ανήκουν στη συνέχεια μόνιμα στο pipeline. Το OWASP συνιστά ρητά τέτοιους ελέγχους, ως hook πριν από το check-in και στο CI.

Πώς βοηθά συγκεκριμένα η PHP SOS;

  • Ελέγχουμε όλα τα domains και τους υποτομείς σας για προσβάσιμους φακέλους ελέγχου εκδόσεων.
  • Αποκλείουμε αμέσως την πρόσβαση και αλλάζουμε το deployment σε πακέτα χωρίς δεδομένα εκδόσεων.
  • Ψάχνουμε το ιστορικό για μυστικά και συνοδεύουμε την αντικατάσταση των επηρεασμένων προσβάσεων.
  • Αξιολογούμε τα αρχεία καταγραφής πρόσβασης και τεκμηριώνουμε αν και πότε ανακτήθηκαν δεδομένα.

Αυτά τα μέτρα είναι μέρος της σκλήρυνσης διακομιστή για διακομιστές ιστού PHP.

Συχνές ερωτήσεις

Πώς προκύπτει ένας δημόσιος φάκελος .git;

Συνήθως από ένα deployment με git clone ή git pull απευθείας στο webroot. Ο φάκελος .git με ολόκληρο το ιστορικό εκδόσεων βρίσκεται τότε δίπλα στο index.php, και χωρίς αποκλεισμό ο διακομιστής ιστού παραδίδει τα αρχεία του.

Αρκεί να διαγράψω τον φάκελο .git;

Για το μέλλον ναι, για το παρελθόν όχι. Αν ο φάκελος ήταν προσβάσιμος, το περιεχόμενο μπορεί να έχει ήδη αντιγραφεί. Στοιχεία πρόσβασης που βρίσκονταν κάποτε στο αποθετήριο πρέπει γι' αυτό να αντικατασταθούν.

Βοηθά να αφαιρέσω εκ των υστέρων στοιχεία πρόσβασης από το ιστορικό Git;

Εμποδίζει τα νέα αντίγραφα να τα περιέχουν. Όποιος έχει ήδη ανακτήσει το αποθετήριο, διατηρεί τις παλιές καταστάσεις. Αποφασιστική είναι γι' αυτό η αντικατάσταση των στοιχείων πρόσβασης και όχι μόνο η αναδιατύπωση του ιστορικού.

Αφορά αυτό και άλλα συστήματα ελέγχου εκδόσεων;

Ναι. Και φάκελοι όπως το .svn ή το .hg περιέχουν δεδομένα του έργου και δεν πρέπει ποτέ να είναι προσβάσιμοι στο webroot. Ένας γενικός αποκλεισμός αρχείων και φακέλων που αρχίζουν με τελεία καλύπτει όλες αυτές τις περιπτώσεις.

Πηγές

Άμεση επικοινωνία

Κάθε ώρα μετράει. Γράψτε μας τώρα.

Περιγράψτε σύντομα το σύστημα, την έκδοση PHP και ό,τι παρατηρείτε. Θα επικοινωνήσουμε μαζί σας, θα διευκρινίσουμε την κατάσταση και θα εργαστούμε εξ αποστάσεως μέχρι το περιστατικό να κλείσει και να τεκμηριωθεί.

Άμεση βοήθεια