제한 없는 파일 업로드

제한 없는 파일 업로드

설명

업로드된 파일의 이름, 확장자, MIME 타입, 저장 위치를 검증하지 않으면 실행 가능한 파일이나 위험한 콘텐츠가 저장될 수 있습니다.

잠재적 영향

웹셸 업로드, 악성 파일 배포, 임의 파일 덮어쓰기가 가능합니다.

해결 방법

서버 생성 파일명을 사용하고, 확장자와 MIME 타입을 허용 목록으로 검증하며, 업로드 디렉터리에서 실행 권한을 제거합니다.

예시

변경 전

php
<?php
$target = 'uploads/' . basename($_FILES['uploaded']['name']);
move_uploaded_file($_FILES['uploaded']['tmp_name'], $target);

변경 후

php
<?php
if ($_FILES['uploaded']['error'] === UPLOAD_ERR_OK
    && mime_content_type($_FILES['uploaded']['tmp_name']) === 'image/png') {
    $target = '/var/app/uploads/' . bin2hex(random_bytes(16)) . '.png';
    move_uploaded_file($_FILES['uploaded']['tmp_name'], $target);
}

설명:

  • 변경 전: 업로드된 파일 이름이나 경로가 유형, 확장자, 저장 대상을 검증하지 않고 사용됩니다.
  • 변경 후: 업로드 오류와 콘텐츠 타입을 확인하고, 사용자 파일명 대신 서버가 생성한 이름으로 실행 경로 밖의 업로드 디렉터리에 저장합니다.

이 예시는 업로드 처리의 일부입니다. 실제 서비스에서는 크기를 제한하고 허용한 파일 형식의 내용을 검증하며, 저장 실패도 처리하세요. /var/app/uploads/는 웹 서버가 파일을 실행하지 않는 위치로 별도 구성해야 합니다.

참조