อะไรคือฟังก์ชั่นการฆ่าเชื้ออินพุต PHP ที่ดีที่สุด


161

ฉันพยายามหาฟังก์ชั่นที่ฉันสามารถผ่านสายทั้งหมดของฉันผ่านการฆ่าเชื้อ ดังนั้นสตริงที่ออกมาจะปลอดภัยสำหรับการแทรกฐานข้อมูล แต่มีฟังก์ชั่นการกรองจำนวนมากออกมีฉันไม่แน่ใจว่าสิ่งที่ฉันควรใช้ / ต้องการ

โปรดช่วยฉันเติมลงในช่องว่าง:

function filterThis($string) {
    $string = mysql_real_escape_string($string);
    $string = htmlentities($string);
    etc...
    return $string;
}

4
สำหรับการแทรกมันเป็นการดีที่จะฆ่าเชื้อ SQL injection โดยใช้ mysql_real_escape_string เมื่อคุณใช้ข้อมูลที่เลือก (ในเอาต์พุต html หรือในสูตร / ฟังก์ชัน php) ที่คุณควรใช้ htmlentities
davidosomething

ดูstackoverflow.com/questions/60174/…สำหรับคำตอบเฉพาะสำหรับการล้างการแทรกฐานข้อมูล (เป็นตัวอย่างของ PDO ซึ่งคนอื่น ๆ ได้กล่าวถึงด้านล่าง)
Pat

คำตอบ:


433

หยุด!

คุณกำลังทำผิดพลาดที่นี่ โอ้ไม่คุณเลือกฟังก์ชั่น PHP ที่เหมาะสมเพื่อทำให้ข้อมูลของคุณปลอดภัยยิ่งขึ้น ไม่เป็นไร. ความผิดพลาดของคุณอยู่ในลำดับของการดำเนินการและวิธีการใช้ฟังก์ชันเหล่านี้และที่ไหน

สิ่งสำคัญคือการเข้าใจถึงความแตกต่างระหว่างการฆ่าเชื้อและการตรวจสอบความถูกต้องของข้อมูลผู้ใช้การหลีกเลี่ยงข้อมูลสำหรับการจัดเก็บและการหลีกเลี่ยงข้อมูลเพื่อการนำเสนอ

ฆ่าเชื้อโรคและตรวจสอบข้อมูลผู้ใช้

เมื่อผู้ใช้ส่งข้อมูลคุณต้องแน่ใจว่าพวกเขาได้มอบสิ่งที่คุณคาดหวัง

การฆ่าเชื้อและการกรอง

ตัวอย่างเช่นถ้าคุณคาดหวังตัวเลข ให้แน่ใจว่าข้อมูลที่ส่งเป็นจำนวน นอกจากนี้คุณยังสามารถส่งข้อมูลผู้ใช้เป็นประเภทอื่นได้ ทุกอย่างที่ส่งจะได้รับการปฏิบัติเหมือนเป็นสตริงดังนั้นการบังคับให้ข้อมูลตัวเลขที่รู้จักกันเป็นจำนวนเต็มหรือลอยทำให้การฆ่าเชื้อนั้นรวดเร็วและไม่เจ็บปวด

แล้วเขตข้อมูลข้อความและ textareas แบบฟรีฟอร์มล่ะ คุณต้องตรวจสอบให้แน่ใจว่าไม่มีอะไรที่ไม่คาดคิดในฟิลด์เหล่านั้น ส่วนใหญ่คุณต้องตรวจสอบให้แน่ใจว่าฟิลด์ที่ไม่ควรมีเนื้อหา HTML ใด ๆ ไม่มี HTML จริงๆ มีสองวิธีที่คุณสามารถจัดการกับปัญหานี้ได้

ครั้งแรกที่คุณสามารถลองหลบหนีการป้อนข้อมูล HTML htmlspecialcharsที่มี คุณไม่ควรใช้htmlentitiesเพื่อทำให้เป็นกลาง HTML เนื่องจากจะทำการเข้ารหัสอักขระที่เน้นเสียงและอักขระอื่น ๆ ที่คิดว่าจำเป็นต้องเข้ารหัสเช่นกัน

ประการที่สองคุณสามารถลองลบ HTML ที่เป็นไปได้ strip_tagsรวดเร็วและง่าย แต่ก็เลอะเทอะ ตัวกรอง HTMLทำงานอย่างละเอียดมากขึ้นทั้งในการแยก HTML ทั้งหมดออกและยังอนุญาตรายการที่อนุญาตของแท็กและแอตทริบิวต์ผ่าน

PHP เวอร์ชันใหม่มาพร้อมกับส่วนขยายตัวกรองซึ่งเป็นวิธีที่ครอบคลุมในการฆ่าเชื้ออินพุตของผู้ใช้

การตรวจสอบ

ตรวจสอบให้แน่ใจว่าข้อมูลที่ส่งปราศจากเนื้อหาที่ไม่คาดคิดนั้นเป็นเพียงครึ่งหนึ่งของงาน คุณต้องลองและตรวจสอบให้แน่ใจว่าข้อมูลที่ส่งมีค่าที่คุณสามารถใช้งานได้จริง

หากคุณคาดหวังว่าจะมีตัวเลขระหว่าง 1 ถึง 10 คุณจะต้องตรวจสอบค่านั้น หากคุณกำลังใช้อินพุตตัวเลขยุค HTML5 แฟนซีใหม่ที่มีสปินเนอร์และขั้นตอนตรวจสอบให้แน่ใจว่าข้อมูลที่ส่งนั้นสอดคล้องกับขั้นตอน

หากข้อมูลนั้นมาจากสิ่งที่ควรเป็นเมนูแบบเลื่อนลงตรวจสอบให้แน่ใจว่าค่าที่ส่งเป็นข้อมูลที่ปรากฏในเมนู

สิ่งที่เกี่ยวกับการป้อนข้อความที่ตอบสนองความต้องการอื่น ๆ ยกตัวอย่างเช่นปัจจัยการผลิตวันที่ควรจะผ่านการตรวจสอบstrtotimeหรือระดับ DateTime วันที่ที่กำหนดควรอยู่ในช่วงที่คุณคาดหวัง แล้วที่อยู่อีเมลล่ะ ที่กล่าวถึงก่อนหน้านี้การขยายตัวกรองสามารถตรวจสอบว่ามีที่อยู่เป็นรูปแบบที่ดี แต่ฉันเป็นแฟนของห้องสมุด is_email

เช่นเดียวกับการควบคุมรูปแบบอื่นทั้งหมด มีปุ่มตัวเลือกหรือไม่ ตรวจสอบกับรายการ มีช่องทำเครื่องหมาย? ตรวจสอบกับรายการ มีไฟล์อัพโหลดไหม ตรวจสอบให้แน่ใจว่าไฟล์เป็นประเภทที่คาดหวังและจัดการกับชื่อไฟล์เช่นข้อมูลผู้ใช้ที่ไม่มีการกรอง

เบราว์เซอร์ที่ทันสมัยทุกอันมาพร้อมกับชุดเครื่องมือสำหรับนักพัฒนาที่สมบูรณ์ซึ่งถูกสร้างขึ้นมาเพื่อให้ทุกคนจัดการกับฟอร์มของคุณได้ง่าย รหัสของคุณควรถือว่าผู้ใช้ลบข้อ จำกัด ฝั่งไคลเอ็นต์ทั้งหมดในเนื้อหาของฟอร์มอย่างสมบูรณ์ !

การหนีข้อมูลสำหรับการจัดเก็บ

เมื่อคุณแน่ใจแล้วว่าข้อมูลของคุณอยู่ในรูปแบบที่คาดหวังและมีค่าที่คาดไว้เท่านั้นคุณต้องกังวลเกี่ยวกับการเก็บข้อมูลนั้นไว้ในที่จัดเก็บ

กลไกการจัดเก็บข้อมูลทุกตัวมีวิธีการเฉพาะเพื่อให้แน่ใจว่าข้อมูลได้รับการยกเว้นและเข้ารหัสอย่างเหมาะสม หากคุณกำลังสร้าง SQL แล้ววิธีที่ยอมรับเพื่อส่งผ่านข้อมูลในการสืบค้นผ่านงบเตรียมด้วยตัวยึด

หนึ่งในวิธีที่ดีกว่าที่จะทำงานร่วมกับฐานข้อมูล SQL ที่สุดใน PHP เป็นส่วนขยาย PDO มันเป็นไปตามรูปแบบที่พบบ่อยของการเตรียมความพร้อมคำสั่ง , ผูกพันตัวแปรคำสั่งแล้วส่งคำสั่งและตัวแปรไปยังเซิร์ฟเวอร์ หากคุณยังไม่ได้ทำงานด้วย PDO ก่อนที่นี่เป็นที่ดีงาม MySQL ที่มุ่งเน้นการกวดวิชา

บางฐานข้อมูล SQL มีนามสกุลพิเศษของพวกเขาเองใน PHP รวมทั้งSQL Server , PostgreSQLและSQLite 3 ส่วนขยายเหล่านั้นแต่ละรายการได้เตรียมการสนับสนุนคำสั่งที่ดำเนินการในรูปแบบเตรียมผูก - รันเดียวกับ PDO บางครั้งคุณอาจต้องใช้ส่วนขยายเหล่านี้แทน PDO เพื่อสนับสนุนคุณสมบัติหรือพฤติกรรมที่ไม่ได้มาตรฐาน

MySQL ยังมีส่วนขยาย PHP ของตัวเอง พวกเขาทั้งสองในความเป็นจริง. คุณเพียงต้องการที่เคยใช้หนึ่งเรียกว่าmysqli นามสกุล "mysql" เดิมเลิกใช้แล้วและไม่ปลอดภัยหรือมีเหตุผลที่จะใช้ในยุคปัจจุบัน

ฉันไม่ใช่แฟนของ mysqli วิธีที่จะทำการเชื่อมโยงตัวแปรในข้อความสั่งที่เตรียมไว้นั้นไม่ยืดหยุ่นและอาจทำให้เกิดความเจ็บปวดในการใช้งาน หากมีข้อสงสัยให้ใช้ PDO แทน

หากคุณไม่ได้ใช้ฐานข้อมูล SQL เพื่อจัดเก็บข้อมูลของคุณให้ตรวจสอบเอกสารประกอบสำหรับส่วนต่อประสานฐานข้อมูลที่คุณใช้เพื่อกำหนดวิธีการส่งผ่านข้อมูลอย่างปลอดภัย

เมื่อเป็นไปได้ตรวจสอบให้แน่ใจว่าฐานข้อมูลของคุณเก็บข้อมูลของคุณในรูปแบบที่เหมาะสม เก็บหมายเลขไว้ในช่องตัวเลข เก็บวันที่ในช่องวันที่ เก็บเงินไว้ในฟิลด์ทศนิยมไม่ใช่ฟิลด์ทศนิยม ตรวจสอบเอกสารที่จัดทำโดยฐานข้อมูลของคุณเกี่ยวกับวิธีการจัดเก็บข้อมูลประเภทต่าง ๆ อย่างถูกต้อง

หนีข้อมูลเพื่อการนำเสนอ

ทุกครั้งที่คุณแสดงข้อมูลต่อผู้ใช้คุณต้องตรวจสอบให้แน่ใจว่าข้อมูลได้รับการยกเว้นอย่างปลอดภัยเว้นแต่คุณจะรู้ว่าไม่ควรหลีกเลี่ยงข้อมูลนั้น

เมื่อเปล่ง HTML คุณควรส่งข้อมูลใด ๆ ที่ผู้ใช้จัดหาผ่านhtmlspecialcharsมา ในความเป็นจริงเพียงครั้งเดียวที่คุณไม่ควรทำเช่นนี้คือเมื่อคุณรู้ว่าผู้ใช้ให้ HTML และคุณรู้ว่ามันถูกทำให้สะอาดแล้วโดยใช้บัญชีขาว

บางครั้งคุณต้องสร้าง Javascript โดยใช้ PHP Javascript ไม่มีกฎการหลบหนีเช่นเดียวกับ HTML! วิธีที่ปลอดภัยเพื่อให้ค่าใช้จ่ายให้กับจาวาสคริปต์ผ่าน PHP json_encodeเป็นผ่าน

และอื่น ๆ

มีความแตกต่างในการตรวจสอบข้อมูลอีกมากมาย

ยกตัวอย่างเช่นการเข้ารหัสชุดอักขระอาจจะเป็นกับดักขนาดใหญ่ ใบสมัครของคุณควรปฏิบัติตามแนวทางปฏิบัติที่ระบุไว้ใน " UTF-8 ไปตลอดทาง " มีการโจมตีสมมุติฐานที่สามารถเกิดขึ้นได้เมื่อคุณปฏิบัติต่อข้อมูลสตริงเป็นชุดอักขระที่ไม่ถูกต้อง

ก่อนหน้านี้ฉันพูดถึงเครื่องมือดีบักของเบราว์เซอร์ เครื่องมือเหล่านี้สามารถใช้เพื่อจัดการข้อมูลคุกกี้ คุกกี้ควรจะถือว่าเป็นผู้ใช้ป้อนข้อมูลที่ไม่น่าเชื่อถือ

การตรวจสอบความถูกต้องของข้อมูลและการหลบหนีเป็นเพียงส่วนหนึ่งของความปลอดภัยของเว็บแอปพลิเคชัน คุณควรทำให้ตัวเองตระหนักถึงวิธีการโจมตีเว็บแอปพลิเคชันเพื่อให้คุณสามารถสร้างการป้องกันได้


และเมื่อระบุให้ตรวจสอบให้แน่ใจว่าอยู่ในรายการการเข้ารหัสที่สนับสนุน
ชาร์ลส์

3
และอย่าใช้ htmlentities เลยแทนที่ด้วย htmlspecialchars เพื่อแทนที่เพียง<>ไม่ใช่ตัวละครทุกตัวที่เป็นนิติบุคคล
Your Common Sense

6
เพียงให้แน่ใจว่าไม่ได้โทรhtmlspecialcharsสองครั้งเพราะเขาพูดถึงมันในส่วน "เมื่อผู้ใช้ส่งข้อมูล" และในส่วน "เมื่อแสดงข้อมูล"
Savageman

2
upvoted คำตอบที่เป็นประโยชน์ที่สุดที่ฉันได้อ่านจาก Q&A มากมายเกี่ยวกับ SQL Injection
akinuri

คำตอบที่มีคุณภาพอย่างแน่นอนพร้อมคำอธิบายและลิงก์มากมายสำหรับผู้ใช้ในอนาคตเพื่อสำรวจตัวเลือกเพิ่มเติม เตรียมพร้อมจากฉันด้วย ...
James Walker

32

ฆ่าเชื้อที่มีประสิทธิภาพมากที่สุดในการฉีดป้องกัน SQL เป็น parameterization PDOใช้ การใช้การค้นหาแบบกำหนดพารามิเตอร์แบบสอบถามจะถูกแยกออกจากข้อมูลเพื่อที่จะกำจัดภัยคุกคามของการฉีด SQL ลำดับที่หนึ่ง

ในแง่ของการลบ HTML strip_tagsน่าจะเป็นความคิดที่ดีที่สุดสำหรับการลบ HTML เพราะมันจะลบทุกอย่างออกไป htmlentitiesมันทำหน้าที่เหมือนกันดังนั้นมันก็ใช้ได้เช่นกัน หากคุณต้องการที่จะแยกซึ่ง HTML เพื่อขอใบอนุญาต (นั่นคือคุณต้องการให้บางแท็ก) คุณควรใช้ตัวแยกวิเคราะห์เป็นผู้ใหญ่ที่มีอยู่เช่นHTML เพียวริฟายเออ


2
อ๊ะฉันเขียนกำแพงข้อความขนาดยักษ์เพียงเพราะฉันไม่เห็นมีใครพูดถึงเครื่องฟอก HTML และที่นี่คุณก็เอาชนะฉันได้ภายใน 40 นาที ;)
Charles

3
คุณไม่ควรตัด HTML ออกเท่านั้น? IMO คุณไม่ควรเปลี่ยนข้อมูลป้อนเข้า - คุณไม่มีทางรู้ว่าคุณต้องการมันเมื่อใด
Joe Phillips

11

ฐานข้อมูลอินพุต - วิธีป้องกัน SQL Injection

  1. ตรวจสอบเพื่อให้แน่ใจว่าข้อมูลของประเภทจำนวนเต็มถูกต้องโดยตรวจสอบให้แน่ใจว่าจริงแล้วเป็นจำนวนเต็ม
    • ในกรณีที่ไม่ใช่สตริงคุณจำเป็นต้องตรวจสอบให้แน่ใจว่าข้อมูลจริงเป็นประเภทที่ถูกต้อง
    • ในกรณีของสตริงที่คุณต้องตรวจสอบให้แน่ใจว่าสตริงนั้นล้อมรอบด้วยเครื่องหมายคำพูดในแบบสอบถาม (แน่นอนมิฉะนั้นจะไม่สามารถใช้งานได้)
  2. ป้อนค่าลงในฐานข้อมูลขณะที่หลีกเลี่ยงการฉีด SQL (mysql_real_escape_string หรือแบบสอบถามที่กำหนดพารามิเตอร์)
  3. เมื่อดึงค่าจากฐานข้อมูลให้แน่ใจว่าได้หลีกเลี่ยงการโจมตี Cross Site Scripting โดยทำให้แน่ใจว่า HTML ไม่สามารถถูกแทรกลงในหน้า (htmlspecialchars)

คุณต้องหลีกเลี่ยงการป้อนข้อมูลผู้ใช้ก่อนที่จะแทรกหรือปรับปรุงลงในฐานข้อมูล นี่เป็นวิธีที่เก่ากว่าที่จะทำ คุณต้องการใช้การค้นหาแบบกำหนดพารามิเตอร์ตอนนี้ (อาจมาจากคลาส PDO)

$mysql['username'] = mysql_real_escape_string($clean['username']);
$sql = "SELECT * FROM userlist WHERE username = '{$mysql['username']}'";
$result = mysql_query($sql);

เอาต์พุตจากฐานข้อมูล - วิธีป้องกัน XSS (Cross Site Scripting)

ใช้htmlspecialchars()เฉพาะเมื่อแสดงผลข้อมูลจากฐานข้อมูล เช่นเดียวกับเครื่องฟอก HTML ตัวอย่าง:

$html['username'] = htmlspecialchars($clean['username'])

และสุดท้าย ... สิ่งที่คุณขอ

ฉันต้องชี้ให้เห็นว่าถ้าคุณใช้วัตถุ PDO กับแบบสอบถามแบบใช้พารามิเตอร์ (วิธีที่เหมาะสมในการทำ) จากนั้นไม่มีวิธีง่ายๆที่จะบรรลุเป้าหมายนี้ได้อย่างง่ายดาย แต่ถ้าคุณใช้ 'mysql' แบบเก่านี่คือสิ่งที่คุณต้องการ

function filterThis($string) {
    return mysql_real_escape_string($string);
}

5

5 เซนต์ของฉัน

ไม่มีใครที่นี่เข้าใจวิธีการmysql_real_escape_stringทำงาน ฟังก์ชั่นนี้ไม่กรองหรือ "ฆ่าเชื้อ" อะไร
ดังนั้นคุณไม่สามารถใช้ฟังก์ชั่นนี้เป็นฟิลเตอร์อเนกประสงค์บางตัวที่จะช่วยคุณไม่ให้ฉีด
คุณสามารถใช้งานได้ก็ต่อเมื่อคุณเข้าใจวิธีการทำงานและการใช้งาน

ฉันมีคำตอบสำหรับคำถามที่คล้ายกันมากที่ฉันเขียนไปแล้ว: ใน PHP เมื่อส่งสตริงไปยังฐานข้อมูลฉันควรดูแลตัวละครที่ผิดกฎหมายโดยใช้ htmlspecialchars () หรือใช้นิพจน์ทั่วไปหรือไม่?
โปรดคลิกเพื่อรับคำอธิบายแบบเต็มเพื่อความปลอดภัยด้านฐานข้อมูล

สำหรับ htmlentities - Charles บอกให้คุณแยกฟังก์ชั่นเหล่านี้ออก
แค่คิดว่าคุณกำลังจะแทรกข้อมูลที่สร้างโดยผู้ดูแลระบบที่ได้รับอนุญาตให้โพสต์ HTML ฟังก์ชั่นของคุณจะทำให้เสีย

แม้ว่าฉันจะแนะนำต่อ htmlentities ฟังก์ชั่นนี้ล้าสมัยไปนานแล้ว หากคุณต้องการที่จะเปลี่ยนเพียง<, >และ"ตัวละครในประโยชน์ของความปลอดภัย HTML - ใช้ฟังก์ชั่นที่ได้รับการพัฒนาโดยเจตนาเพื่อวัตถุประสงค์ที่ - ทางhtmlspecialchars ()อย่างใดอย่างหนึ่ง


1
mysql_real_escape_stringหนีอักขระที่จำเป็นภายในสตริง มันไม่ได้กรองหรือฆ่าเชื้ออย่างเคร่งครัด แต่การใส่สตริงในเครื่องหมายคำพูดไม่ใช่ (และทุกคนทำมันฉันแทบไม่เคยเห็นคำถามเกี่ยวกับมันเลย) ดังนั้นจะไม่มีสิ่งใดถูกสุขลักษณะเมื่อเราเขียน SQL? ไม่แน่นอน สิ่งที่ช่วยป้องกันการฉีด SQL mysql_real_escape_stringคือการใช้ นอกจากนี้คำพูดที่ล้อมรอบ แต่ทุกคนทำและถ้าคุณทดสอบสิ่งที่คุณทำคุณจะจบลงด้วยข้อผิดพลาดทางไวยากรณ์ของ SQL ที่มีการละเว้นนี้ mysql_real_escape_stringส่วนที่เป็นอันตรายที่แท้จริงคือการจัดการกับ
Savageman

@Savageman ขอโทษเพื่อนคุณเข้าใจอะไรไม่ได้ คุณไม่เข้าใจวิธีการทำงานของ mysql_real_escape_string เครื่องหมายคำพูด "จำเป็นต้องใช้" คือ ฟังก์ชั่นนี้ไม่ได้หรือไม่พูดอะไรเพียงอย่างเดียว ทั้งสองสิ่งนี้ทำงานร่วมกันเท่านั้น การสร้างสตริงการสืบค้นให้ถูกต้องตามหลักไวยากรณ์ไม่ใช่ "ปลอดภัยจากการฉีด" และฉันจะได้รับข้อผิดพลาดทางไวยากรณ์เพียงWHERE id = 1ใด ;)
สามัญสำนึกของคุณ

ลองWHERE my_field = two words(โดยไม่ใส่เครื่องหมายอัญประกาศ) เพื่อรับข้อผิดพลาดทางไวยากรณ์ ตัวอย่างของคุณไม่ดีเพราะมันไม่จำเป็นต้องมีเครื่องหมายคำพูดไม่หนีหายไปเพียงแค่การตรวจสอบตัวเลข นอกจากนี้ฉันไม่ได้พูดคำพูดที่ไร้ประโยชน์ ฉันบอกว่าทุกคนใช้พวกเขาดังนั้นนี่ไม่ใช่สาเหตุของปัญหาเกี่ยวกับการฉีด SQL
Savageman

1
@Savageman ดังนั้นฉันจึงกล่าวว่า: คุณสามารถใช้งานได้เฉพาะเมื่อคุณเข้าใจว่ามันทำงานอย่างไรและใช้งานได้ที่ไหน คุณเพิ่งยอมรับว่า mysql_real_escape_string ไม่สามารถใช้ได้ทุกที่ สำหรับeveryone use themคุณสามารถตรวจสอบรหัสได้ที่นี่ใน SO หลายคนไม่ได้ใช้เครื่องหมายคำพูดกับตัวเลข ไปคิด โปรดจำไว้ว่าฉันไม่ได้พูดถึงที่นี่สิ่งที่คุณพูดและคุณไม่ได้ ฉันแค่อธิบายกฎความปลอดภัยฐานข้อมูลพื้นฐาน คุณควรเรียนรู้มากกว่าที่จะเถียงเปล่า ๆ ไม่มีใครพูดถึงคำพูดหรือการคัดเลือกที่นี่ แต่ m_r_e_s ราวกับว่ามันเป็นเวทมนตร์ สิ่งที่ฉันพูดคุยเกี่ยวกับ
สามัญสำนึกของคุณ

1
เพิ่มขึ้นหนึ่งรายการเช่นเดียวกับ @Charles ในฐานะที่เป็นสามเณรปฏิสัมพันธ์ของฐานข้อมูล ... ทำให้สิ่งต่าง ๆ ปลอดภัยสำหรับอินพุตและจอแสดงผลอักขระพิเศษปัญหาการฉีดเป็นเส้นโค้งการเรียนรู้ที่สูงชันมาก การอ่านโพสต์และของเขา (เช่นเดียวกับ PHP อื่น ๆ ของคุณตอบคำถามอื่น ๆ ได้ช่วยฉันอย่างมาก Tx สำหรับการป้อนข้อมูลทั้งหมดของคุณ
James Walker

2

สำหรับการแทรกฐานข้อมูลสิ่งที่คุณต้องมีคือmysql_real_escape_string(หรือใช้การค้นหาแบบกำหนดพารามิเตอร์) htmlentitiesคุณมักไม่ต้องการที่จะแก้ไขข้อมูลก่อนที่จะบันทึกมันซึ่งเป็นสิ่งที่จะเกิดขึ้นถ้าคุณใช้ ซึ่งจะนำไปสู่ความยุ่งเหยิงที่อ่านไม่ออกในภายหลังเมื่อคุณวิ่งผ่านhtmlentitiesอีกครั้งเพื่อแสดงที่ใดที่หนึ่งบนหน้าเว็บ

ใช้htmlentitiesเมื่อคุณแสดงข้อมูลบนเว็บเพจบางแห่ง

ค่อนข้างเกี่ยวข้องถ้าคุณส่งข้อมูลที่ส่งไปที่ไหนสักแห่งในอีเมลเช่นเดียวกับแบบฟอร์มการติดต่อให้แน่ใจว่าได้ตัดบรรทัดใหม่จากข้อมูลใด ๆ ที่จะใช้ในส่วนหัว (เช่นจาก: ชื่อและที่อยู่อีเมลย่อย ฯลฯ )

$input = preg_replace('/\s+/', ' ', $input);

หากคุณไม่ทำสิ่งนี้ก่อนเวลาที่บอทสแปมจะค้นพบแบบฟอร์มของคุณและใช้ในทางที่ผิดฉันก็เรียนรู้วิธีการที่ยากลำบาก


2

1) ใช้ตัวกรอง phpดั้งเดิมฉันได้ผลลัพธ์ดังต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่


(สคริปต์ต้นฉบับ: https: // RunFor github.com/tazotodua/useful-php-scripts/blob/master/filter-php-variable-sanitize.php )


ภาพของคุณไม่โหลด (หรืออาจต้องลงชื่อเข้าใช้ที่ Google ไดรฟ์)
Kristoffer Bohmann

2

ขึ้นอยู่กับประเภทของข้อมูลที่คุณใช้ สิ่งที่ดีที่สุดในการใช้งานทั่วไปmysqli_real_escape_stringคือตัวอย่างเช่นคุณรู้ว่าจะไม่มีเนื้อหา HTML การใช้ strip_tags จะเพิ่มความปลอดภัยเป็นพิเศษ

นอกจากนี้คุณยังสามารถลบอักขระที่คุณรู้ว่าไม่ควรอนุญาต


1

ฉันมักจะแนะนำให้ใช้แพ็คเกจการตรวจสอบขนาดเล็กเช่น GUMP: https://github.com/Wixel/GUMP

สร้างฟังก์ชั่นพื้นฐานทั้งหมดที่คุณจัดเรียงไลบรารีเช่นนี้และแทบจะเป็นไปไม่ได้ที่จะลืมเรื่องสุขอนามัย "mysql_real_escape_string" ไม่ใช่ทางเลือกที่ดีที่สุดสำหรับการกรองที่ดี (เช่น "Your Common Sense" อธิบาย) - และหากคุณลืมที่จะใช้เพียงครั้งเดียวระบบทั้งหมดของคุณจะถูกโจมตีผ่านการฉีดและการข่มขู่ที่น่ารังเกียจอื่น ๆ


1

สำหรับทุกคนที่นี่พูดถึงและพึ่งพา mysql_real_escape_string คุณต้องสังเกตว่าฟังก์ชันนั้นเลิกใช้แล้วใน PHP5 และไม่มีอยู่ใน PHP7 อีกต่อไป

IMHO วิธีที่ดีที่สุดในการทำภารกิจนี้ให้สำเร็จคือใช้การสืบค้นแบบ Parametrized ผ่านการใช้ PDO เพื่อโต้ตอบกับฐานข้อมูล ตรวจสอบสิ่งนี้: https://phpdelusions.net/pdo_examples/select

ใช้ตัวกรองเพื่อประมวลผลอินพุตของผู้ใช้เสมอ ดูhttp://php.net/manual/es/function.filter-input.php


สิ่งนี้ไม่ได้ตอบคำถาม พิจารณาแก้ไขคำตอบของคุณเพื่อรวมโซลูชัน
kris

หวังว่าคุณจะชอบมัน!
Kuntur

ฉันทำ. คำตอบที่ดี!
kris

ฉันขอแนะนำให้ทำหมายเหตุว่าใน PHP 7 mysqli_real_escape_string()มีให้ใช้งาน
Chris

สวัสดีคริสโซลูชั่นที่เปิดเผยที่นี่อ้างอิงถึง mysql_real_escape_string ฉันสังเกตเห็นว่าผู้อ่านต่อจากนี้ไปว่ามันไม่มีอยู่อีกต่อไปใน PHP7 และเสนอทางเลือกอื่นโดยใช้ PDO (และตัวกรอง) ไม่ใช่ mysqli คุณสามารถเพิ่มบันทึกอธิบายโซลูชันโดยใช้สิ่งที่คุณแนะนำ ขอแสดงความนับถือ
Kuntur

0

คุณใช้mysql_real_escape_string ()ในโค้ดที่คล้ายกับโค้ดต่อไปนี้

$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
  mysql_real_escape_string($user),
  mysql_real_escape_string($password)
);

ในฐานะที่เป็นเอกสารกล่าวว่าจุดประสงค์ของมันคือการหลบหนีตัวอักษรพิเศษในสตริงเป็นอาร์กิวเมนต์คำนึงถึงตัวอักษรชุดปัจจุบันของการเชื่อมต่อเพื่อที่จะมีความปลอดภัยที่จะวางไว้ในmysql_query () เอกสารยังเพิ่ม:

หากต้องใส่ข้อมูลไบนารีต้องใช้ฟังก์ชันนี้

htmlentities ()ใช้เพื่อแปลงอักขระบางตัวในเอนทิตีเมื่อคุณส่งออกสตริงในเนื้อหา HTML


0

นี่คือหนึ่งในวิธีที่ฉันกำลังฝึก

  1. ฝัง csrf และโทเค็นล่อใจเกลือพร้อมกับคำขอที่จะทำโดยผู้ใช้และตรวจสอบพวกเขาทั้งหมดเข้าด้วยกันจากการร้องขอ อ้างอิงที่นี่
  2. ตรวจสอบให้แน่ใจว่าไม่ต้องพึ่งพาคุกกี้ฝั่งไคลเอ็นต์มากเกินไปและต้องฝึกใช้เซสชันฝั่งเซิร์ฟเวอร์
  3. เมื่อมีการแยกวิเคราะห์ข้อมูลให้แน่ใจว่ายอมรับเฉพาะชนิดข้อมูลและวิธีการถ่ายโอน (เช่น POST และ GET)
  4. ตรวจสอบให้แน่ใจว่าใช้ SSL สำหรับ ur webApp / App
  5. ตรวจสอบให้แน่ใจว่าได้สร้างคำขอเซสชันฐานเวลาเพื่อ จำกัด คำขอสแปมโดยเจตนา
  6. เมื่อข้อมูลถูกแยกวิเคราะห์ไปยังเซิร์ฟเวอร์ตรวจสอบให้แน่ใจว่าได้ตรวจสอบคำขอควรทำในวิธีการที่คุณต้องการเช่น json, html และอื่น ๆ ... จากนั้นดำเนินการต่อ
  7. หลบหนีแอ็ตทริบิวต์ที่ผิดกฎหมายทั้งหมดจากอินพุตโดยใช้ escape type ... เช่น realescapestring
  8. หลังจากนั้นตรวจสอบความถูกต้องของรูปแบบข้อมูลชนิดที่คุณต้องการจากผู้ใช้
    ตัวอย่าง:
    - อีเมล: ตรวจสอบว่าการป้อนข้อมูลอยู่ในรูปแบบอีเมลที่ถูกต้อง
    - ข้อความ / สตริง: ตรวจสอบเฉพาะการป้อนข้อมูลที่เป็นรูปแบบข้อความเท่านั้น (สตริง)
    - หมายเลข: ตรวจสอบรูปแบบตัวเลขที่ได้รับอนุญาต
    - ฯลฯ Pelase อ้างถึงไลบรารีการตรวจสอบอินพุต php จากพอร์ทัล php
    - เมื่อผ่านการตรวจสอบแล้วโปรดดำเนินการต่อโดยใช้คำสั่ง SQL / PDO ที่เตรียมไว้
    - เมื่อเสร็จแล้วให้แน่ใจว่าได้ออกและยุติการเชื่อมต่อ
    - อย่าลืมล้างค่าออกเมื่อทำ

ทั้งหมดที่ฉันเชื่อว่าเพียงพอสำหรับวินาทีพื้นฐาน ควรป้องกันการโจมตีที่สำคัญทั้งหมดจากแฮกเกอร์

สำหรับการรักษาความปลอดภัยฝั่งเซิร์ฟเวอร์คุณอาจต้องการตั้งค่าใน apache / htaccess ของคุณเพื่อ จำกัด การเข้าถึงและการป้องกันหุ่นยนต์และการป้องกันการกำหนดเส้นทาง .. มีสิ่งที่ต้องทำมากมายสำหรับการรักษาความปลอดภัยฝั่งเซิร์ฟเวอร์นอกเหนือจากวินาทีของระบบบนฝั่งเซิร์ฟเวอร์

คุณสามารถเรียนรู้และรับสำเนาวินาทีจากระดับ htaccess apache วินาที (rpactices ทั่วไป)


0
function sanitize($string,$dbmin,$dbmax){
$string = preg_replace('#[^a-z0-9]#i', '', $string); //useful for strict cleanse, alphanumeric here
$string = mysqli_real_escape_string($con, $string); //get ready for db
if(strlen($string) > $dbmax || strlen($string) < $dbmin){
    echo "reject_this"; exit();
    }
return $string;
}

0

แล้วเรื่องนี้ล่ะ

$string = htmlspecialchars(strip_tags($_POST['example']));

หรือสิ่งนี้

$string = htmlentities($_POST['example'], ENT_QUOTES, 'UTF-8');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.