PHP 8.1의 새로운 기능 중 하나는 이제 PHP의 $_FILES 슈퍼 전역 변수에 사용자가 업로드한 파일의 경로가 포함된다는 것입니다.
이 정보는 전체 디렉토리 업로드를 지원하는 브라우저에서 제공되며 PHP 8.1부터 이 정보는 PHP 애플리케이션에서 디렉토리 업로드를 지원하는 데 사용할 수 있습니다.
webkitdirectory 속성을 포함하는 파일 필드가 있는 HTML 양식은 디렉토리 업로드 필드로 간주됩니다.
이 기능을 지원하는 브라우저를 사용하면 개별 파일 대신 전체 디렉토리를 선택할 수 있습니다.
사용자가 업로드할 디렉토리를 선택하면 브라우저는 모든 하위 디렉토리와 해당 파일을 포함하여 해당 디렉토리 내의 모든 파일을 서버에 제출합니다.
PHP 8.1 이상을 실행하는 PHP 응용 프로그램에서 파일 경로는 $_FILES 슈퍼 전역에서 사용할 수 있으며 응용 프로그램은 파일 이름, 크기 등과 같은 다른 정보와 함께 파일 경로를 저장할 수 있습니다.
브라우저에서 제공하는 파일 경로는 사용자 입력이므로 그대로 처리해야 합니다. 이러한 필드는 드문 일이 아닌 경로 탐색 공격에 취약합니다.
웹킷디렉토리 속성
webkitdirectory는 type=file인 입력 HTML 요소에서 사용할 수 있는 HTML 속성입니다. 브라우저 표준은 아니지만 Chrome 6+, Firefox 50+, Edge 13+ 및 Safari 11.1+를 포함한 모든 주요 브라우저에서 지원합니다.
HTML directory upload field
디렉토리 업로드는 type=file인 표준 입력 요소를 재사용합니다. webkitdirectory를 지원하는 브라우저는 디렉토리 업로드 창을 제공하고 나머지는 표준 파일 업로드 창을 제공합니다.
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="dir_upload[]" webkitdirectory multiple />
<input type="submit" value="Upload"/>
</form>
PHP에서 파일 경로 액세스
사용자가 디렉토리 업로드 필드를 사용하여 디렉토리를 업로드하면 브라우저는 파일 이름, 파일 크기 및 파일 내용과 함께 해당 파일에 대한 상대 경로를 제출합니다.
PHP에서 파일 업로드 정보는 $_FILES 슈퍼 글로벌에서 접근합니다. PHP 8.1 이전에는 브라우저에서 제공하는 상대 파일 경로가 $_FILES로 전달되지 않아 디렉토리 업로드의 디렉토리 계층 구조를 결정할 수 없었습니다.
PHP 8.1에서 이 정보는 $_FILES로 전달되며 디렉토리 업로드를 상대 경로와 함께 저장하거나 서버에서 디렉토리를 재생성하는 데 사용할 수 있습니다.
$_FILES 배열에는 HTML 입력 필드의 이름 속성으로 인덱싱된 파일 업로드 정보가 포함됩니다. 위의 예에서 입력 필드의 이름은 name=dir_upload[]입니다. 이는 $_FILES 배열에 직접 $_FILES['dir_upload'] 배열이 포함되어 있으며 이 배열에는 name, tmp_name 등과 같은 키가 있는 연관 배열이 포함되어 있음을 의미합니다.
project_files
├── data
│ └── data.csv
├── outlines
│ ├── intro.doc
│ └── welcome.doc
├── presentation.pdf
├── presentations
│ ├── ayesh.ppt
│ ├── mentor.doc
│ └── phpwatch.ppt
└── report.xls
위와 유사한 디렉토리 구조에서 $_FILES 배열은 $_FILES['dir_upload']['name']에서 기본 파일 이름만 반환합니다.
var_dump($_FILES);
array(1) {
["dir_upload"]=> array(6) {
["name"]=> array(8) {
[0]=> string(8) "data.csv"
[1]=> string(16) "presentation.pdf"
[2]=> string(9) "intro.doc"
[3]=> string(11) "welcome.doc"
[4]=> string(10) "report.xls"
[5]=> string(12) "phpwatch.ppt"
[6]=> string(9) "ayesh.ppt"
[7]=> string(10) "mentor.doc"
}
...type, tmp_name, error, size
$_FILES['dir_upload']['name'] 배열에서 상대 경로가 누락되어 사용자 파일 시스템에서 파일에 대한 상대 경로를 검색할 수 없게 하는 방법에 주목하십시오.
PHP 8.1 이상부터 파일에 대한 상대 경로를 포함하는 $_FILES의 각 파일 업로드 필드에 새 배열이 추가됩니다.
var_dump($_FILES);
array(1) {
["dir_upload"]=> array(6) {
["name"]=> array(8) {
[0]=> string(8) "data.csv"
[1]=> string(16) "presentation.pdf"
...
}
+ ["full_path"]=> array(8) {
+ [0]=> string(27) "project-files/data/data.csv"
+ [1]=> string(30) "project-files/presentation.pdf"
+ [2]=> string(32) "project-files/outlines/intro.doc"
+ [3]=> string(34) "project-files/outlines/welcome.doc"
+ [4]=> string(24) "project-files/report.xls"
+ [5]=> string(40) "project-files/presentations/phpwatch.ppt"
+ [6]=> string(37) "project-files/presentations/ayesh.ppt"
+ [7]=> string(38) "project-files/presentations/mentor.doc"
}
...type, tmp_name, error, size
각 파일 업로드 필드의 새로운 full_path 배열은 파일의 전체 경로를 나열합니다.
디렉토리 업로드 시 이제 각 업로드된 파일의 전체 경로를 저장할 수 있습니다. 업로드된 파일을 업로드한 사용자와 동일한 디렉토리 구조에 저장하는 것을 선호하는 응용 프로그램은 파일을 서버의 관련 디렉토리로 재귀적으로 이동하여 저장할 수 있습니다.
Security Hardening
각 $_FILES 필드의 full_path 배열은 사용자가 직접 입력하기 때문에 안전하지 않습니다. 이 배열의 모든 값은 특히 서버의 하위 디렉터리에 업로드된 파일을 저장할 때 잠재적인 취약점을 방지하기 위해 유효성을 검사해야 합니다.
출처 : https://php.watch/articles/php81-directory-uploads
등록된 댓글이 없습니다.