[php] PHP를 사용한 파일 업로드와 크로스 사이트 스크립팅 방어

파일 업로드 기능은 웹 응용 프로그램에서 일반적으로 사용되지만, 사용자의 컴퓨터에 해로운 코드를 실행할 수 있는 보안 취약점에 노출될 수 있습니다. 특히 크로스 사이트 스크립팅 (XSS) 공격으로 인해 공격자가 원격으로 사용자의 컴퓨터를 제어하는 경우 이러한 취약점이 더욱 위험할 수 있습니다. 이를 방지하기 위해 다음과 같은 보안 조치가 필요합니다.

파일 업로드 시 파일 유형 제한

파일 업로드 시 허용 가능한 파일 유형을 명시적으로 지정하여 사용자가 업로드한 파일 중 해로운 파일이 실행되지 않도록 합니다. PHP에서는 $_FILES 배열을 사용하여 파일의 MIME 유형을 확인하고, 이를 통해 허용되지 않는 파일을 거부할 수 있습니다.

$allowedTypes = array('image/jpeg', 'image/png');
if (!in_array($_FILES['file']['type'], $allowedTypes)) {
    // 파일 유형이 허용되지 않을 때의 처리
    // 예: 오류 메시지 출력 또는 파일 업로드 거부
}

이렇게 함으로써 사용자가 업로드한 파일이 실행 가능한 스크립트 파일인지 여부를 확인할 수 있습니다.

파일 이름 처리

사용자가 업로드한 파일 이름에 대해서도 신중한 처리가 필요합니다. 해로운 문자나 경로 조작을 방지하기 위해, 업로드된 파일의 이름을 재정의하거나 안전하게 저장하는 방법을 사용해야 합니다.

$filename = $_FILES['file']['name'];
$uploadPath = 'uploads/' . basename($filename);
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadPath)) {
    // 파일 업로드 성공
} else {
    // 파일 업로드 실패
}

위의 예시에서는 basename 함수를 사용하여 업로드된 파일명에서 경로 정보를 제거하여 안전한 파일명으로 저장하고 있습니다.

파일 내용 검사

파일 내용을 검사하여 바이러스나 악성 코드가 포함되어 있는지 확인해야 합니다. PHP에서는 finfo_file 함수를 사용하여 파일의 MIME 타입을 식별하고, 파일이 텍스트 형식인 경우 file_get_contents 함수를 사용하여 내용을 읽어들여 안전한지 여부를 검사할 수 있습니다.

$fileContents = file_get_contents($_FILES['file']['tmp_name']);
if (strpos($fileContents, 'malicious string') !== false) {
    // 악성 코드가 포함된 파일에 대한 처리
}

출력 보안

사용자가 업로드한 파일을 다운로드할 때 보안 문제가 발생하지 않도록, 해당 파일의 MIME 유형과 파일명을 정확히 제어하고, 파일 다운로드 시 적절한 헤더를 설정하여 보안을 강화해야 합니다.

파일 업로드 및 다운로드 기능을 구현할 때 이러한 보안 조치를 적용하여 보다 안전하고 신뢰할 수 있는 웹 응용 프로그램을 개발할 수 있습니다.