File uploader

File Uploader

<<<<<<< HEAD

Niezabezpieczony file uploader

File uploader jest krytycznym punktem aplikacji, a jego nieodpowiednie zabezpieczonie może doprowadzić do poważnych konsekwencji, jak przeciążenie systemu plików, a nawet przejęcie systemu.

W niezabezpieczonej wersji właściwości plików, takie jak typ lub rozmiar, nie są rzetelnie sprawdzane. Przykład niewystarczającego zabezpieczenia stanowi poniższy kod.

< input type="file" name="fileToUpload" id = "fileToUpload" accept="image/*" >

Podjęto próbę ograniczenia typu przesyłanych plików, za pomocą atrybutu "accept". Aby obejść to zabezpieczenie wystarczy skorzystać z narzędzia DevTools i usunąć ten fragment kodu HTML, a następnie przesłać plik niebędący obrazem. Co więcej, nie został ograniczony maksymalny rozmiar pliku, zatem atakujący móglby spróbować obciążyć serwer wieloma plikami o dużym rozmiarze.

Przykład file uploadera, którego jedne zabezpieczenie stanowi atrybut HTML znajduje się poniżej.

Zabezpieczony file uploader

Aby uniknąć ingerencji użytkownika w zabezpieczenia systemu, nie należy umieszczać ich w sekcji dostępnej dla użytkownika za pomocą narzędzi deweloperskich. Poniżej przedstawione zabezpieczenia wykonywane są po stronie serwera.

Pierwszym krokiem jest sprawdzenie typu przesyłanego pliku. W przykładowym kodzie poniżej celem jest upewnienie się, że plik jest obrazem.

                          
$correct = 0;
@$check_error = getimagesize($_FILES["fileToUpload"]["tmp_name"]);

// Checking if an actual image
if( $check_error!== false) {
// Image
    $correct = 1;
} else {
// Not an image
    $correct = 0;
}

// Check the extension
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$uploaded_type = $_FILES[ 'fileToUpload' ][ 'type' ];

if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
        && $imageFileType != "gif" && ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' )) {
//Wrong extension
        $correct = 0;
}
                

Funkcja getimagesize() sprawdza typ MIME przesyłanego pliku i zwraca wartość false, jeśli nie jest on typem obrazu. Funkcja pathinfo() umożliwia uzyskanie informacji o ścieżce pliku, a następnie wyłuskanie informacji o rozszerzeniu w celu porównania z dozwolonymi rozszerzeniami obrazów.

W celu pozbycia się metadanych, wówczas można na nowo zakodować obraz za pomocą funkcji imagecreateformjpg() lub imagecreatefrompng().

                                      
if( $uploaded_type == 'image/jpeg' ) {
	$img = imagecreatefromjpeg( $uploaded_tmp );
    imagejpeg( $img, $temp_file, 100);
}
else {
	$img = imagecreatefrompng( $uploaded_tmp );
	imagepng( $img, $temp_file, 9);
}
imagedestroy( $img );

Kolejnym krokiem jest sprawdzenie, czy rozmiar pliku mieści się w określonych granicach.


// Check the size
if ($_FILES["fileToUpload"]["size"] > 100000) {
    //Too large
$correct = 0;
}

Zaprezentowana poniżej poprawiona wersja file uploadera spełnia wszystkie opisane powyżej wymagania, co czyni ją znacznie bezpieczniejszym rozwiązaniem.