# Αποτροπή του Server-Side Request Forgery (SSRF) στην PHP

> Αποτροπή SSRF στην PHP: λίστες επιτρεπόμενων, μόνο HTTPS, χωρίς ανακατευθύνσεις, έλεγχος επιλυμένης IP και όρια εξερχόμενης κίνησης. Με κώδικα cURL.

Πηγή: https://phpsos.de/el/blog/ssrf-in-php/  
Ημερομηνία: 25/10/2026  
Πάροχος: PHP SOS, Επείγουσα βοήθεια PHP και ασφάλεια διακομιστών. Άμεση βοήθεια μέσω WhatsApp: https://wa.me/491736494914?text=%CE%93%CE%B5%CE%B9%CE%B1%20%CF%83%CE%B1%CF%82%2C%20PHP%20SOS%2C%20%CF%87%CF%81%CE%B5%CE%B9%CE%B1%CE%B6%CF%8C%CE%BC%CE%B1%CF%83%CF%84%CE%B5%20%CE%B2%CE%BF%CE%AE%CE%B8%CE%B5%CE%B9%CE%B1%20%CE%BC%CE%B5%20%CF%84%CE%BF%CE%BD%20%CE%B4%CE%B9%CE%B1%CE%BA%CE%BF%CE%BC%CE%B9%CF%83%CF%84%CE%AE%20PHP%20%CE%BC%CE%B1%CF%82.%20%CE%95%CF%84%CE%B1%CE%B9%CF%81%CE%B5%CE%AF%CE%B1%3A%20%E2%80%A6%20%CE%99%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%CF%82%3A%20%E2%80%A6

**Εν ολίγοις:** Το SSRF στην PHP το αποτρέπετε αν η εφαρμογή σας ανακτά μόνο διευθύνσεις που βρίσκονται σε σταθερή λίστα επιτρεπόμενων, αποκλειστικά μέσω HTTPS, χωρίς να ακολουθεί ανακατευθύνσεις. Η επιλυμένη διεύθυνση IP ελέγχεται απέναντι σε ιδιωτικά και δεσμευμένα εύρη και στη συνέχεια καρφώνεται για τη σύνδεση. Ένα τείχος προστασίας για την εξερχόμενη κίνηση φροντίζει ώστε τα εσωτερικά συστήματα να παραμένουν απρόσιτα ακόμη και σε περίπτωση σφάλματος στον κώδικα.

## Όταν ο δικός σας διακομιστής κάνει αιτήματα για λογαριασμό ξένων

Προεπισκοπήσεις συνδέσμων σε ένα chat, εισαγωγή μιας εικόνας προϊόντος μέσω URL, webhooks προς συστήματα συνεργατών, ένας αναγνώστης feed σε ένα CMS: πολλές εφαρμογές PHP ανακτούν διευθύνσεις που έδωσε ένας χρήστης. Αυτό είναι χρήσιμη λειτουργία και ταυτόχρονα μια πόρτα προς τα μέσα.

Στο Server-Side Request Forgery, εν συντομία SSRF, ένας επιτιθέμενος κάνει την εφαρμογή να στείλει ένα αίτημα προς έναν προορισμό της επιλογής του. Το κόλπο: το αίτημα προέρχεται από τον ίδιο τον διακομιστή. Φτάνει έτσι σε συστήματα που είναι αποκλεισμένα από έξω, όπως βάσεις δεδομένων, διεπαφές διαχείρισης στο εσωτερικό δίκτυο, υπηρεσίες που ακούν μόνο στο localhost ή τις υπηρεσίες μεταδεδομένων των παρόχων cloud.

Στο OWASP Top 10 του 2021 το SSRF ήταν ξεχωριστή κατηγορία. Σε έργα PHP η αδυναμία εμφανίζεται συχνά εκεί όπου κάποιος έφτιαξε βιαστικά μια λειτουργία «προσθήκη εικόνας μέσω URL».

## SSRF στην PHP: ποιες συναρτήσεις ανακτούν διευθύνσεις

Δεν ανακτά διευθύνσεις μόνο το cURL. Τα εξής σημεία πρέπει να έχετε υπόψη:

| Συνάρτηση ή τομέας | Γιατί είναι σχετικό |
|---|---|
| cURL (`curl_exec()`) | πιο συχνός δρόμος, πολλά πρωτόκολλα δυνατά |
| `file_get_contents()`, `fopen()`, `copy()` με URL | χρησιμοποιούν URL wrappers όταν είναι ενεργό το `allow_url_fopen` |
| `getimagesize()` και βιβλιοθήκες εικόνας | μπορούν να φορτώσουν απομακρυσμένα αρχεία |
| Επεξεργασία XML, πελάτες SOAP | φορτώνουν υπό προϋποθέσεις εξωτερικούς πόρους |
| Βιβλιοθήκες HTTP όπως το Guzzle | βασίζονται σε cURL ή streams, ίδιοι κανόνες |

Αν η εφαρμογή σας δεν χρειάζεται να ανοίγει απομακρυσμένα αρχεία μέσω συναρτήσεων αρχείων, απενεργοποιήστε το `allow_url_fopen` στον διακομιστή. Ένα συγγενικό θέμα, η ενσωμάτωση αρχείων μέσω διαδρομών από το αίτημα, πραγματεύεται ο οδηγός [Αποτροπή του Local και Remote File Inclusion](https://phpsos.de/el/ratgeber/lfi-rfi/).

## Η άμυνα σε πέντε βήματα

Το OWASP συνιστά έναν συνδυασμό μέτρων που το καθένα ξεχωριστά θα μπορούσε να παρακαμφθεί, μαζί όμως αντέχουν:

1. **Λίστα επιτρεπόμενων αντί για ελεύθερο URL:** Το καλύτερο είναι ο χρήστης να επιλέγει μόνο από γνωστούς προορισμούς ή να δίνει απλώς ένα αναγνωριστικό, και η εφαρμογή να φτιάχνει μόνη της τη διεύθυνση.
2. **Να επιτρέπεται μόνο HTTPS:** Αποκλείστε στο cURL άλλα πρωτόκολλα όπως `file`, `gopher` ή `ftp`, και για τις ανακατευθύνσεις.
3. **Να μην ακολουθούνται ανακατευθύνσεις:** Μια επιτρεπόμενη διεύθυνση μπορεί αλλιώς να ανακατευθύνει σε εσωτερικό προορισμό.
4. **Έλεγχος και καρφίτσωμα της επιλυμένης διεύθυνσης:** Επιλύστε το hostname, ελέγξτε την IP απέναντι σε ιδιωτικά εύρη, loopback και link-local και χρησιμοποιήστε ακριβώς αυτή την IP για τη σύνδεση. Αλλιώς μια δεύτερη επίλυση DNS μπορεί να δώσει άλλο προορισμό.
5. **Περιορισμός του δικτύου:** Ο διακομιστής ιστού επιτρέπεται να φτάνει προς τα έξω μόνο τους προορισμούς που χρειάζεται.

## Ένα ασφαλές πρότυπο με cURL

Το παρακάτω παράδειγμα υλοποιεί τα βήματα 1 έως 4 για IPv4. Τα hostnames και η ροή είναι παραδείγματα· για IPv6 ισχύουν οι ίδιοι έλεγχοι.

```php
<?php
declare(strict_types=1);

function ladeVonPartner(string $url): string
{
    $teile = parse_url($url);
    if (!is_array($teile) || ($teile['scheme'] ?? '') !== 'https'
        || isset($teile['user']) || isset($teile['pass']) || isset($teile['port'])) {
        throw new InvalidArgumentException('Adresse nicht erlaubt.');
    }

    $host = strtolower($teile['host'] ?? '');
    $erlaubt = ['api.partner.example', 'bilder.partner.example'];
    if (!in_array($host, $erlaubt, true)) {
        throw new InvalidArgumentException('Ziel nicht erlaubt.');
    }

    $ip = gethostbyname($host);
    $oeffentlich = filter_var($ip, FILTER_VALIDATE_IP,
        FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
    if ($oeffentlich === false) {
        throw new RuntimeException('Ziel löst auf eine nicht erlaubte Adresse auf.');
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_FOLLOWLOCATION  => false,
        CURLOPT_PROTOCOLS       => CURLPROTO_HTTPS,
        CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS,
        CURLOPT_RESOLVE         => [$host . ':443:' . $ip],
        CURLOPT_CONNECTTIMEOUT  => 3,
        CURLOPT_TIMEOUT         => 10,
    ]);
    $antwort = curl_exec($ch);
    if ($antwort === false) {
        throw new RuntimeException('Abruf fehlgeschlagen.');
    }
    return $antwort;
}
```

Ορισμένες λεπτομέρειες είναι σημαντικές. Το `gethostbyname()` επιστρέφει σε περίπτωση σφάλματος το hostname· ο επόμενος έλεγχος IP το εντοπίζει. Οι σημαίες `FILTER_FLAG_NO_PRIV_RANGE` και `FILTER_FLAG_NO_RES_RANGE` αποκλείουν σύμφωνα με το εγχειρίδιο της PHP, μεταξύ άλλων, τα εύρη 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 και 169.254.0.0/16. Από την PHP 8.2 υπάρχει επιπλέον το `FILTER_FLAG_GLOBAL_RANGE`, που επιτρέπει μόνο διευθύνσεις με παγκόσμια ισχύ. Το `CURLOPT_RESOLVE` φροντίζει ώστε το cURL να χρησιμοποιεί ακριβώς την ελεγμένη διεύθυνση, ενώ διατηρούνται το hostname και ο έλεγχος πιστοποιητικού.

Δύο ακόμη σημεία περιορίζουν όσα μαθαίνει ένας επιτιθέμενος από μια αδυναμία SSRF. Μην επιστρέφετε στον χρήστη αφιλτράριστες τις απαντήσεις και τα μηνύματα σφάλματος του προορισμού που ανακτήθηκε: ήδη η διάκριση ανάμεσα σε «σύνδεση απορρίφθηκε» και «υπέρβαση χρόνου» αποκαλύπτει ποιες εσωτερικές υπηρεσίες υπάρχουν. Και περιορίστε τη διάρκεια και το μέγεθος της απάντησης, ώστε η λειτουργία να μην μπορεί να χρησιμοποιηθεί για υπερφόρτωση του δικού σας διακομιστή. Webhooks προς διευθύνσεις που καταχωρούν οι ίδιοι οι πελάτες, είναι καλύτερο να αποστέλλονται από μια ουρά και όχι κατά τη διάρκεια του τρέχοντος αιτήματος.

> **Σημαντικό:**
> Αν η εφαρμογή σας πρέπει πραγματικά να ανακτά τυχαίες διευθύνσεις, για παράδειγμα για προεπισκοπήσεις συνδέσμων, μεταφέρετε αυτή τη λειτουργία σε χωριστή υπηρεσία χωρίς πρόσβαση στο εσωτερικό δίκτυο. Μια λίστα επιτρεπόμενων δεν είναι τότε εφικτή, ο διαχωρισμός του δικτύου όμως είναι ακόμη πιο σημαντικός.

## Το επίπεδο δικτύου ως δίχτυ ασφαλείας

Οι έλεγχοι στον κώδικα μπορεί να έχουν κενά, για παράδειγμα όταν δύο βιβλιοθήκες αναλύουν διαφορετικά ένα URL. Το OWASP συμβουλεύει να αντιμετωπίζονται τέτοιες ασυμφωνίες ως απόρριψη και επιπλέον να τίθενται όρια σε επίπεδο δικτύου. Ένας διακομιστής ιστού χρειάζεται προς τα έξω συνήθως λίγους προορισμούς: πηγές πακέτων, παρόχους πληρωμών και αποστολών, αναμεταδότη αλληλογραφίας, συγκεκριμένες διεπαφές.

Ένα τείχος προστασίας για την εξερχόμενη κίνηση βοηθά διπλά. Σταματά τα αιτήματα SSRF προς το εσωτερικό δίκτυο και δυσκολεύει μετά από μια εισβολή, για παράδειγμα μέσω μιας εκδοχής PHP χωρίς patch, τη λήψη πρόσθετων εργαλείων. Πώς χτίζετε τους κανόνες, περιγράφει το [Τείχος προστασίας για διακομιστή ιστού: ανοίξτε μόνο τις απαραίτητες θύρες](https://phpsos.de/el/blog/firewall-fuer-webserver/). Ποιες συνδέσεις δημιουργεί πραγματικά ένας διακομιστής, δείχνει το [Έλεγχος των εξερχόμενων συνδέσεων ενός διακομιστή](https://phpsos.de/el/blog/ausgehende-verbindungen-pruefen/).

Σε περιβάλλοντα cloud ανήκει εδώ η σκληρυμένη παραλλαγή της υπηρεσίας μεταδεδομένων. Το OWASP αναφέρει για το AWS τη μετάβαση στο IMDSv2 και την απενεργοποίηση του IMDSv1.

## Εντοπισμός του SSRF στον υπάρχοντα κώδικα

Μια γρήγορη αρχή είναι η αναζήτηση σημείων όπου οι συναρτήσεις ανάκτησης λαμβάνουν τιμές από το αίτημα:

```bash
grep -rnE "(curl_init|file_get_contents|fopen|getimagesize|copy)\s*\(" src/ --include="*.php" | grep -E '\$_(GET|POST|REQUEST)|\$url'
grep -rn "CURLOPT_FOLLOWLOCATION" src/ --include="*.php"
```

Τα αποτελέσματα είναι εργασίες ελέγχου. Ιδιαίτερα προσεκτικά πρέπει να εξετάσετε συναρτήσεις που χρησιμοποιούν οι διαχειριστές: εισαγωγές, ρυθμίσεις webhook, έλεγχοι ενημερώσεων πρόσθετων.

Εύκολα παραβλέπονται οι γεννήτριες PDF που μετατρέπουν HTML με ενσωματωμένες εικόνες ή φύλλα στυλ σε έγγραφα. Αν ένα μέρος αυτού του HTML προέρχεται από είσοδο χρήστη, για παράδειγμα σε τιμολόγια με ελεύθερα επιλεγόμενο λογότυπο, η γεννήτρια ανακτά υπό προϋποθέσεις διευθύνσεις που καθορίζει ο χρήστης. Ελέγξτε εκεί τις ρυθμίσεις για τη φόρτωση απομακρυσμένων πόρων και απενεργοποιήστε την αν δεν χρειάζεται.

## Πώς βοηθά συγκεκριμένα η PHP SOS;

- Εντοπίζουμε όλα τα σημεία όπου η εφαρμογή σας ανακτά διευθύνσεις, και σε πρόσθετα και βιβλιοθήκες.
- Χτίζουμε μια κεντρική συνάρτηση ανάκτησης με λίστα επιτρεπόμενων, περιορισμό πρωτοκόλλων και έλεγχο IP.
- Ορίζουμε κανόνες για την εξερχόμενη κίνηση και προστατεύουμε τις υπηρεσίες μεταδεδομένων σε περιβάλλοντα cloud.
- Ελέγχουμε την υλοποίηση από έξω και τεκμηριώνουμε τους επιτρεπόμενους προορισμούς.

Έναν ανεξάρτητο έλεγχο της εφαρμογής σας περιγράφει ο [Έλεγχος ασφαλείας και δοκιμή διείσδυσης](https://phpsos.de/el/leistungen/sicherheitsaudit-penetrationstest/).


## Συχνές ερωτήσεις

**Ποιες συναρτήσεις PHP μπορούν να καταχραστούν για SSRF;**  
Όλες όσες ανακτούν μια διεύθυνση από είσοδο χρήστη: cURL, file_get_contents και fopen με URL wrappers, συναρτήσεις εικόνας και XML που φορτώνουν απομακρυσμένα αρχεία, καθώς και βιβλιοθήκες για webhooks, feeds ή προεπισκοπήσεις συνδέσμων.

**Αρκεί να αποκλείσω τις εσωτερικές διευθύνσεις IP;**  
Από μόνο του όχι. Το OWASP χαρακτηρίζει τις λίστες αποκλεισμού ευάλωτες σε παράκαμψη και συνιστά λίστες επιτρεπόμενων. Επιπλέον η εφαρμογή πρέπει να χρησιμοποιεί ακριβώς τη διεύθυνση που έλεγξε και δεν επιτρέπεται να ακολουθεί ανακατευθύνσεις.

**Γιατί είναι το SSRF ιδιαίτερα κρίσιμο στο cloud;**  
Οι πάροχοι cloud παρέχουν στα instances εσωτερικές υπηρεσίες μεταδεδομένων, μέσω των οποίων μπορούν εν μέρει να ανακτηθούν στοιχεία πρόσβασης. Αν μια εφαρμογή μπορεί να στείλει εκεί αιτήματα, ένας επιτιθέμενος μπορεί να φτάσει σε αυτά τα δεδομένα μέσω της εφαρμογής. Οι πάροχοι προσφέρουν σκληρυμένες παραλλαγές αυτών των υπηρεσιών, που πρέπει να είναι ενεργοποιημένες.

**Τι προσφέρει ένα τείχος προστασίας για την εξερχόμενη κίνηση;**  
Περιορίζει ποιους προορισμούς μπορεί να φτάσει εν γένει ο διακομιστής. Ακόμη κι αν αποτύχει ένας έλεγχος στον κώδικα, τα εσωτερικά συστήματα παραμένουν τότε απρόσιτα. Επιπλέον δυσκολεύει μετά από μια εισβολή τη λήψη κακόβουλου κώδικα και τη διαρροή δεδομένων.

## Πηγές

- [OWASP Server-Side Request Forgery Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html)
- [Εγχειρίδιο της PHP: σταθερές φίλτρων](https://www.php.net/manual/de/filter.constants.php)
- [Εγχειρίδιο της PHP: σταθερές cURL](https://www.php.net/manual/de/curl.constants.php)
