PHP: evitare la superficialità nella gestione dinamica dei file

PHP: evitare la superficialità nella gestione dinamica dei file

Gestire con superficialità i file in PHP è sempre rischioso.

Partiamo dall'esempio volutamente errato di uno script che comprime i file CSS:


function minify( $css ) {
	$css = preg_replace( '#\s+#', ' ', $css );
	$css = preg_replace( '#/\*.*?\*/#s', '', $css );
	$css = str_replace( '; ', ';', $css );
	$css = str_replace( ': ', ':', $css );
	$css = str_replace( ' {', '{', $css );
	$css = str_replace( '{ ', '{', $css );
	$css = str_replace( ', ', ',', $css );
	$css = str_replace( '} ', '}', $css );
	$css = str_replace( ';}', '}', $css );

	return trim( $css );
}

header( 'Content-type: text/css' );

$file = isset( $_GET[ 'css' ] ) ? $_GET[ 'css' ] : ''; // Molto pericoloso

$content = file_get_contents( $_SERVER['DOCUMENT_ROOT'] . $file ); // Potenziale problema
echo minify( $content ); // Il problema diventa reale

Innanzitutto non sappiamo affatto se la variabile $file contenga un nome di file CSS valido o meno. Potrebbe ad esempio contenere un nome in un formato diverso da quello CSS o addirittura dello shell code. Quindi occorre innanzitutto validare il nome del file:


if(preg_match('/^[a-z0-9]+\.css$/', $file)) { // Il formato del nome può variare
    // Valido
}

A questo punto non sappiamo ancora se il file richiesto esiste. Occorre verificarlo:


$css_file = $_SERVER['DOCUMENT_ROOT'] . $file;
if(file_exists($css_file)) {
    if(is_readable($css_file)) {
        // Possiamo usarlo
    }
}

Abbiamo verificato che il file esiste e che è accessibile. Potremmo aggiungere un'ulteriore verifica:


$finfo = finfo_open( FILEINFO_MIME_TYPE );
$mimetype = finfo_file( $finfo, $css_file );
finfo_close( $finfo );

if( $mimetype == 'text/css' ) {
    // È un file CSS al 100%
}

Qui abbiamo verificato anche il corretto tipo MIME del file richiesto. La ridondanza non sempre è un male.

Torna su