2011-09-06 50 views
12

Tôi phát triển một tập lệnh php để thay thế tập lệnh hiện tại, sẽ có nhiều tiếp xúc với các thị trường/quốc gia khác nhau. Kịch bản này giữa những người khác cung cấp chức năng tải ảnh lên.Cách tiếp cận bảo mật tải lên hình ảnh PHP

Sau nhiều lần đọc về vấn đề này, tôi đã làm theo cách tiếp cận được mô tả bên dưới. Tôi sẽ đánh giá cao ý kiến ​​của bạn về an ninh của nó.

  1. Ảnh được tải lên trong thư mục riêng 777 bên ngoài gốc web.
  2. Kiểm tra các tiện ích mở rộng được liệt kê trắng được thực hiện (chỉ cho phép jpg, gifs, png) mọi thứ khác bị xóa.
  3. Sử dụng getimagesize để kiểm tra kích thước tối đa và hiệu lực ảnh.
  4. Kiểm tra đối sánh mimetype và phần mở rộng tệp.
  5. Thay đổi kích thước ảnh đã tải lên thành thứ nguyên std (sử dụng imagecopyresampled).
  6. Lưu tệp đã tạo dưới dạng jpg.
  7. Xóa tệp gốc.
  8. Lưu ảnh bằng tên mới (không phải ngẫu nhiên) tức là img51244.jpg.
  9. Di chuyển ảnh mới sang các thư mục con khác của một thư mục công cộng (777 quyền) theo thuật toán không thể dự đoán được. Tức là, img10000.jpg sẽ được lưu trữ tại photos/a/f/0/img10000.jpg trong khi img10001.jpg sẽ được lưu trữ tại photos/0/9/3/img10001.jpg. Điều này được thực hiện vì các lý do khác (sử dụng tên miền phụ cho nội dung tĩnh phân phát hoặc sử dụng CDN).

Tập lệnh sẽ chạy trên máy chủ chuyên dụng của Linux.

+0

không có gì xảy ra với tôi ở đây. ngoài sự cho phép 777 trên thư mục - như tôi hiểu nó, nếu nó có 777 quyền, nó không phải là riêng tư. nhưng như xa như tôi có thể nói điều này sẽ chỉ thực sự quan trọng nếu máy chủ của bạn đã bị xâm nhập (mà không có khả năng cho tôi thông qua kịch bản này ít nhất) – jammypeach

+2

777 không âm thanh an toàn. Có thể liên quan đến http://stackoverflow.com/questions/3644138/secure-user-image-upload-capabilities-in-php – ajreal

+0

Âm thanh rất tốt với tôi, ngoại trừ có thể cho các quyền rất tự do. Có lẽ chúng có thể bị hạn chế một chút? Nếu không, điều này làm mọi thứ cần thiết tôi có thể nghĩ đến, bao gồm việc xóa dữ liệu EXIF ​​ –

Trả lời

3

Bạn cũng nên kiểm tra kích thước tệp đã tải lên, vì số lần tải xuống đôi khi có thể vượt quá bộ nhớ RAM sẵn có. Nó cũng tốt để giả định rằng kịch bản của bạn có thể sụp đổ bất cứ lúc nào (ví dụ như khi điện đi xuống), vì vậy bạn nên thực hiện một số thủ tục dọn dẹp để loại bỏ các tập tin trái, không cần thiết.

+1

Các tệp có thể tải lên tối đa đã bị giới hạn trong php.ini. – Maerlyn

+0

Có, nhưng nó không có nghĩa là nó đủ để tránh vượt quá giới hạn RAM. –

+0

Nếu nó vượt quá kích thước trong php.ini bạn không nhận được một tên tập tin trong '$ _FILES' - vì vậy bạn không thể kiểm tra kích thước của nó. – Maerlyn

-1

Đó là một cách tiếp cận khá hoàn chỉnh, nhưng tôi không thấy bất kỳ cơ chế ngăn chặn thực thi mã nào.

Bạn nên đảm bảo rằng nội dung của hình ảnh không bao giờ được bao gồm (có bao gồm hoặc yêu cầu cuộc gọi) hoặc được thực hiện thông qua eval().

Nếu không, mã php được bao gồm ở cuối tệp có thể được thực thi.

Bạn cũng có thể thử phát hiện mã php bên trong nội dung hình ảnh (với file_get_contents, và sau đó regex tìm kiếm "<? Php" chẳng hạn) nhưng tôi không thể tìm được cách an toàn 100% để loại bỏ mã đáng ngờ mà không phá hủy một số hình ảnh (hợp lệ).

+0

Tôi không thấy mã PHP sẽ được thực thi trong tệp JPG trừ khi máy chủ của bạn bị định cấu hình sai? –

+0

Nó không có điểm, vì nó rõ ràng không ai sẽ gọi eval hoặc bao gồm trên hình ảnh. Tôi không thể nghĩ ra bất kỳ kịch bản nào mà một người nào đó sẽ nghĩ đến việc đó (trừ khi anh ta chỉ mới bắt đầu sử dụng PHP). –

+0

Tệp gốc sẽ bị xóa ngay sau khi các ảnh đã được lấy mẫu lại xuất hiện. chỉ được sử dụng với các hàm php sau theo thứ tự đó: move_uploaded_file, tệp, getimagesize, imagecreatefromjpeg, imagecopyresampled. – Alex

4
  1. Một thư mục với chmod 0777, theo định nghĩa, công khai cho người dùng khác đăng nhập vào máy chủ của bạn, chứ không phải riêng tư. Các quyền chính xác sẽ là 700 và được sở hữu bởi apache (hoặc bất kỳ người dùng nào mà máy chủ web của bạn chạy). Tôi không chắc chắn lý do tại sao bạn sẽ không sử dụng thư mục tạm thời mặc định của php ở đây, vì nó có xu hướng ở bên ngoài root web.
  2. Danh sách trắng là một ý tưởng hay. Hãy cẩn thận để thực hiện đúng. Ví dụ: regexp /.png/ thực sự khớp với apng.php.
  3. Bước này là một ý tưởng tuyệt vời. Về cơ bản nó kiểm tra tập tin ma thuật.
  4. Không hoàn toàn cần thiết. Trong hai bước trước, chúng tôi đã xác định rằng phần mở rộng và định dạng tệp là chính xác. Nếu bạn yêu cầu loại MIME chính xác được chỉ định bởi máy khách, bạn cũng nên kiểm tra xem loại MIME đã cho và loại MIME đã xác định ở trên có tương đương hay không.

Các bước 5 đến 8 không liên quan đến bảo mật.

Bước 9: Tôi giả định rằng trang web của bạn cho phép mọi người xem mọi ảnh. Nếu đó không phải là trường hợp, bạn nên có một lược đồ URL với URL dài hơn đáng kể (nói, hashsum của hình ảnh).

+1

(-1) 777 không có nghĩa là công khai về khả năng truy cập thông qua web - đây là những gì anh ta đang nói đến. Và ví dụ regex của bạn ngụ ý rằng đây là bất kỳ imortance anyway ... và BTW exe là một cửa sổ mở rộng ...: -/ – Raffael

+0

@ Raffael1984 Tôi nghĩ rằng phihag biết điều đó. Nó vẫn công khai về mặt * khả năng truy cập tới những người dùng khác trên cùng một máy chủ web *, * là * một vấn đề. Nhưng tôi đồng ý rằng bước 2) là không cần thiết nếu bạn làm 3) đúng –

+0

@ Raffael1984 Đúng. Tôi không chắc chắn tại sao bước đó là cần thiết. Đã cập nhật câu trả lời. – phihag

Các vấn đề liên quan