Domanda

Un collega rispettato insiste sul fatto che la memorizzazione delle immagini sul mio server non è sicura, soprattutto se la struttura del file è facile da supporre (poiché abbiamo gallerie di immagini create dagli utenti, lo schema di denominazione è facile da seguire).

Consiglia invece di archiviare le immagini sopra la radice e di servirle utilizzando fread o fputthrough.

Non riesco a capire quali sarebbero i rischi o perché verrebbero evitati se pubblicati tramite uno script.
Il sovraccarico di un tale script sembra ridicolo.

Capisco che le immagini debbano essere controllate prima di essere memorizzate sul server, ea tal fine sto usando imagemagick per fare una piccola conversione e salvare in jpeg - che dovrebbe sbarazzarsi di qualsiasi scoria, per quanto immagino.

Quindi, le domande alle grandi menti di SO:

  1. Esistono problemi di sicurezza con l'archiviazione delle immagini in locale con percorsi facili da seguire?
  2. Il mio metodo di controllo delle immagini con IM è sicuro?
  3. C'è un motivo per utilizzare PHP per pubblicare le immagini?
  4. Il sovraccarico dell'utilizzo di PHP è davvero notevole?
  5. Usare un CDN farebbe la differenza in termini di sicurezza (NON voglio)?
  6. Mi sto perdendo qualcosa?

Grazie a tutti!

È stato utile?

Soluzione

Sospetto che ciò a cui si riferisce il tuo amico non sia semplicemente il servizio di immagini, ma piuttosto il servizio specifico di immagini fornite dall'utente . Ci sono una serie di problemi di sicurezza nel servire i contenuti forniti dagli utenti. Nel caso delle immagini, ci sono diversi modi per utilizzare il caricamento di un'immagine per fare in modo che il server web esegua il codice. Alcuni di quelli più noti includono:

  • Un file "GIFAR". Essenzialmente, questo è un file GIF e un file jar concatenati. Poiché le informazioni sull'indice per una GIF sono all'inizio e quella per un file jar è alla fine, i due tipi di file possono essere combinati e il risultato è sia una GIF valida che un JAR valido.
  • Più estensioni di file. I server Web supportano più estensioni di file per consentire cose come l'internazionalizzazione. Ad esempio, un file denominato page.html.fr potrebbe mappare alla versione in lingua francese di una pagina. Un file con estensione image.php.jpg o anche image.php.123 potrebbe essere eseguibile come script PHP, a seconda della configurazione del server.
  • Buffer overflow. I formati di file immagine di solito contengono un'intestazione all'inizio che descrive la dimensione e il formato del file. La comprensione delle dimensioni può consentire agli utenti malintenzionati di creare un attacco di overflow del buffer.

Tutti questi esempi portano alla capacità di eseguire codice come server web. Sebbene la funzionalità del sito richieda la possibilità di caricare file, archiviarli in directory non direttamente accessibili da un URL rende più difficile sfruttarli. Allo stesso modo, l'utilizzo di uno script per servirli al posto dei gestori MIME del server web assicura che le immagini vengano trattate come un flusso di dati piuttosto che come un file potenzialmente eseguibile.

Il fatto che questa sicurezza sia ridicola dipende dal numero di utenti, dalla natura dei dati raccolti su di loro e dalla banalità del sito web. Per lo meno, un utente malintenzionato vorrebbe ottenere le password degli utenti a causa della tendenza a sincronizzarli. Un utente sul tuo sito la cui password è ABC123 probabilmente utilizzerà la stessa password per e-mail, siti social e possibili siti bancari e finanziari. Oltre alle password, se i dati che raccogli sui tuoi utenti sono identificabili personalmente o hanno un altro valore di mercato, o se hai semplicemente un numero elevato di utenti, allora devi presumere che il sito sarà un bersaglio. Ciò significa che devi essere più attento a servire i file di immagine forniti dagli utenti, convalidarli molto bene o entrambe le cose.

Non ho una buona risposta sul fatto che l'uso di imagemagick risolva i problemi di sicurezza. Per lo meno, assicurati di utilizzare una versione corrente perché una rapida ricerca ha rilevato una serie di vulnerabilità note. Ricorda che i file di cui ti devi preoccupare potrebbero far saltare in aria imagemagick, anche se non sfruttano una delle vulnerabilità note, quindi assicurati di avere una cattura degli errori VERAMENTE buona.

Altri suggerimenti

Se le immagini non sono private, cioè puoi vederle abbastanza facilmente, semplicemente non vuoi che qualcuno le legga tutte a suo piacimento, dare a ciascuna un nome univoco può essere sufficiente.

Se ce ne sono più di qualche migliaio (e sembra probabile), la creazione di una gerarchia di directory in cui sono memorizzati può anche aiutare a velocizzare l'accesso, aumentando così tanto lo spazio di ricerca da non essere trovati dalla ricerca casuale. Ad esempio: un file chiamato 347168a5d9b4ac5eb386e396f68b2231.jpg può essere inserito in una directory: /images/34/71/68/347168a5d9b4ac5eb386e396f68b2231.jpg La directory multilivello accelera l'accesso evitando la scansione di migliaia di voci di directory e il nome casuale (memorizzato nel database allegato all'elenco di immagini dell'utente in una galleria) impedisce la ricerca di file casuali.

Il sovraccarico di una sceneggiatura del genere sembra ridicolo.

Lo stesso qui.Se le immagini sono pubblicamente accessibili, non vedo assolutamente alcun motivo per farlo.

Se non sono accessibili pubblicamente (cioè devono essere accessibili solo agli utenti che hanno effettuato l'accesso), non c'è modo di aggirare il modo in cui il tuo collega descrive (o utilizzare il X-Sendfile dopo aver eseguito il controllo di accesso,che consente di risparmiare parte dell'overhead se è installato il software necessario).Ma se non è così, il sovraccarico richiesto per questo è pazzo .

Se hai determinato che hai effettivamente bisogno delle immagini per essere sicure, ecco cosa ho usato in un progetto di fumetti (in pratica ho messo tonnellate di fumetti in una directory, e poi quando arriva un poaccedervi uno alla volta)

//check if image should be accessed by the current request...

$fh=fopen($my_image,"rb");

if($fh==NULL){
        exit();
}
rewind($fh);
header("Content-Type: image/png");
header("Content-Length: " . filesize($fn));
fpassthru($fh);

fclose($fh);
exit();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top