클라이언트 측 이미지 처리와 업로드
웹 개발에서 클라이언트 측 이미지 처리는 사용자가 브라우저에서 선택한 이미지 파일을 서버로 안전하게 전송하고 저장하는 과정을 의미합니다. 이 과정에서 가장 중요한 것은 업로드된 파일이 실제로 유효한 이미지인지 검증하는 것입니다. 악성 코드가 포함된 파일이 이미지로 위장해 업로드되는 것을 막아야 하기 때문입니다.
아래 예제는 PHP를 활용해 이미지 파일의 유효성을 검사하고, 정상적인 경우 서버에 저장하는 기본적인 방법을 보여줍니다.
이미지 업로드 처리 코드
클라이언트 측에서 이미지를 처리하고 업로드하려면 다음 코드를 실행해 볼 수 있습니다.
<?php
if (isset($_FILES["image"])) {
$iSize = getimagesize($_FILES["image"]["tmp_name"]);
if ($iSize !== false) {
$myFile = "/tmp/" . basename($_FILES["image"]["name"]);
if (move_uploaded_file($_FILES["image"]["tmp_name"], $myFile)) {
echo "File stored at " . $myFile;
} else {
echo "Image storage failed!";
}
} else {
echo "This isn't an image!";
}
} else {
echo "Image not available to upload!";
}
?>
코드 동작 방식
위 코드의 처리 흐름은 다음과 같습니다.
- 파일 존재 여부 확인: isset($_FILES["image"]) 구문으로 업로드된 파일이 있는지 먼저 검사합니다. 파일이 없으면 업로드 실패 메시지를 출력합니다.
- 이미지 유효성 검사: getimagesize() 함수는 파일이 실제 이미지인지 판별합니다. GIF, JPEG, PNG 등 지원되는 형식의 크기 정보를 반환하며, 이미지가 아니면 false를 반환합니다.
- 파일 저장: basename() 함수로 경로 조작 공격(directory traversal)을 방지한 뒤, move_uploaded_file() 함수로 임시 디렉터리에서 /tmp 폴더로 파일을 이동시킵니다.
- 결과 출력: 저장에 성공하면 파일 경로를, 실패하면 오류 메시지를 화면에 표시합니다.
실무 적용 시 유의 사항
실제 운영 환경에서는 다음과 같은 추가 보안 조치를 함께 고려하는 것이 좋습니다.
- getimagesize()만으로는 모든 위조 파일을 완벽히 차단할 수 없으므로, finfo_file() 또는 exif_imagetype()을 함께 활용하면 더욱 안전합니다.
- 원본 파일명을 그대로 사용하지 말고, 고유한 난수 기반 파일명으로 변경해 저장하는 것이 좋습니다.
- 업로드 디렉터리에는 실행 권한을 제거하고, 웹 루트 외부 또는 외부 접근이 제한된 위치에 파일을 저장하세요.
- 허용할 이미지 확장자와 MIME 타입은 화이트리스트 방식으로 제한하는 것이 바람직합니다.
이처럼 클라이언트에서 전송된 이미지를 서버 측에서 철저히 검증하고 저장하면, 보안 위협을 줄이면서도 안정적인 파일 업로드 기능을 구현할 수 있습니다.