ฉันควรทำให้ที่อยู่อีเมลปลอดภัยก่อนที่จะส่งผ่านไปยังฟังก์ชัน is_email () หรือไม่


13

ฉันใช้is_email()เพื่อตรวจสอบว่าที่อยู่อีเมลที่ผู้ใช้ระบุถูกต้องหรือไม่ ตัวอย่างเช่น:

$email = $_POST['email'];
if ( is_email( $email ) )
    // Do something.

เพื่อความรู้ที่ดีที่สุดของฉันไม่มีสิ่งใดในฟังก์ชั่นนี้เขียนข้อมูลไปยังฐานข้อมูล ฉันควรจะฆ่าเชื้อ$emailก่อนที่จะส่งไปยังฟังก์ชั่นหรือไม่


ไกเซอร์ขอบคุณสำหรับการแก้ไข ก็จริง sanitisation สำหรับฉัน แต่ฉันแน่ใจว่าผู้อ่านส่วนใหญ่ที่นี่จะใช้Z :)
henrywright

คำตอบ:


5

ดูis_email()ฟังก์ชั่นการใช้งาน trac ดูเหมือนว่าคุณไม่จำเป็นต้อง sanatizie เพราะมันเป็นเพียงการทดสอบสตริง ฉันจะพูดต่อไปว่าถ้าฟังก์ชั่นนี้คืนค่าจริงคุณไม่จำเป็นต้องฆ่าเชื้อก่อนที่จะส่งไปยังฐานข้อมูล


ความคิดของฉันเกี่ยวกับการทดสอบสตริง ฉันคิดว่าฉันจะยังคงฆ่าตัวตายก่อนที่จะส่งไปยัง db คุณอาจพูดถูกว่าไม่จำเป็น แต่ฉันเป็นคนทำลายประสาทเมื่อพูดถึงเรื่องเหล่านี้ :)
henrywright

จริงดีกว่าปลอดภัยกว่าขออภัยและค่าใช้จ่ายในการฆ่าเชื้อจะไม่สังเกตเห็นได้เลย
Howdy_McGee

18

WordPress และ PHP หลัก

is_email()ฟังก์ชั่นที่มาเป็นการนำ WordPress ทั่วไปและไม่สามารถทำงานได้อย่างสมบูรณ์กับสิ่งRFC 6531ช่วยให้ เหตุผลหนึ่งอาจจะเป็นที่เริ่มต้น PHP FILTER_VALIDATE_EMAILคงfilter_var()ไม่ดีมากที่การตรวจสอบสิ่งที่เป็นไปตามอินเทอร์เน็ต Engineering Task Force (IETF®)แนวทาง

มาตรฐาน

ประเด็นก็คือว่าRFC 6531ช่วยให้"ตัวอักษร Unicode เกินช่วง ASCII ว่า" นั่นคือ (สำหรับส่วนท้องถิ่น - ก่อน@):

  • ตัวอักษรภาษาอังกฤษตัวพิมพ์ใหญ่และเล็ก (a – z, A – Z) (ASCII: 65–90, 97–122)
  • ตัวเลข0เป็น9(ASCII: 48–57)
  • อักขระพิเศษเหล่านี้: ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • อักขระ.(จุดระยะเวลาหยุดเต็ม) (ASCII: 46) โดยมีเงื่อนไขว่าไม่ใช่อักขระตัวแรกหรือตัวสุดท้ายและจะต้องไม่ปรากฏตามลำดับ (เช่นJohn..Doe@example.comไม่ได้รับอนุญาต)
  • อนุญาตให้ใช้อักขระพิเศษโดยมีข้อ จำกัด พวกเขาเป็น:
    • ช่องว่างและ"(),:;<>@[\](ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91–93)
    • ข้อ จำกัด สำหรับอักขระพิเศษคือต้องใช้เมื่ออยู่ระหว่างเครื่องหมายอัญประกาศเท่านั้นและอักขระ 2 ตัวนั้น (เครื่องหมายแบ็กสแลช \ และเครื่องหมายคำพูด "(ASCII: 92, 34)) จะต้องนำหน้าด้วยแบ็กสแลช\(เช่น"\\"และ"\"") .
  • อนุญาตให้แสดงความคิดเห็นพร้อมวงเล็บที่ส่วนท้ายของส่วนท้องที่ เช่นjohn.smith(comment)@example.comและ(comment)john.smith@example.comเทียบเท่ากับทั้งสอง"john.smith@example.com"แต่john.(comment)smith@example.comจะไม่ถูกต้อง
  • อักขระสากลด้านบนU+007Fซึ่งเข้ารหัสเป็น UTF-8 ได้รับอนุญาตจาก RFC 6531 แม้ว่าระบบอีเมลอาจ จำกัด อักขระที่จะใช้เมื่อกำหนดส่วนภายใน

และสำหรับส่วนส่วนกลาง / โดเมน:

ส่วนชื่อโดเมนของที่อยู่อีเมลต้องเป็นไปตามหลักเกณฑ์ที่เข้มงวด: จะต้องตรงกับข้อกำหนดสำหรับชื่อโฮสต์ซึ่งประกอบด้วยตัวอักษรตัวเลขยัติภังค์และจุด นอกจากนี้ส่วนโดเมนอาจเป็นตัวอักษรที่อยู่ IP ล้อมรอบด้วยเครื่องหมายวงเล็บสี่เหลี่ยมเช่นjsmith@[192.168.2.1]หรือjsmith@[IPv6:2001:db8::1][…]

ที่มา: Wikipedia

สิ่งที่ถูกต้อง?

สิ่งนี้อาจนำไปสู่ความแปลก แต่ที่อยู่อีเมลที่ถูกต้องเช่นนี้

  • localpart.ending.with.dot.@example.com
  • (comment)localpart@example.com
  • "this is v@lid!"@example.com
  • "much.more unusual"@example.com
  • postbox@com
  • admin@mailserver1
  • "()<>[]:,;\\@\"\\\\!#$%&\'*+-/=?^_`{}| ~.a"@example.org
  • " "@example.org

ที่มา: php.net / ผู้แต่ง gt@kani.hu - ตัวอย่างแก้ไขโดยผู้เขียนโพสต์นี้

ขีด จำกัด

นอกจากนี้ยังมีการจำกัดความยาวของโดเมนและท้องถิ่น:

รูปแบบของที่อยู่อีเมลคือlocal-part@domainส่วนในตัวเครื่องอาจมีความยาวสูงสุด 64 ตัวอักษรและชื่อโดเมนอาจมีความยาวสูงสุด 253 ตัวอักษรแต่ความยาวสูงสุด 256 ตัวอักษรสำหรับเส้นทางไปข้างหน้าหรือย้อนกลับจะ จำกัด ที่อยู่อีเมลทั้งหมดไว้ที่ มีความยาวไม่เกิน 254 ตัวอักษร [2] คำจำกัดความเป็นทางการอยู่ใน RFC 5322 (ส่วน 3.2.3 และ 3.4.1) และ RFC 5321 - ด้วยแบบฟอร์มที่อ่านได้มากขึ้นใน RFC 3696 ที่ให้ข้อมูล [3] และ errata ที่เกี่ยวข้อง .

ที่มา: Wikipedia

ข้อ จำกัด ของ WordPress

และนี่คือสิ่งที่ WordPress ตรวจสอบ:

  • ทดสอบความยาวต่ำสุดของอีเมลได้: strlen( $email ) < 3
  • ทดสอบอักขระ @ หลังตำแหน่งแรก: strpos( $email, '@', 1 ) === false
  • ทดสอบอักขระที่ไม่ถูกต้อง: !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
  • ทดสอบลำดับของช่วงเวลา: preg_match( '/\.{2,}/', $domain )
  • ทดสอบช่วงเวลานำหน้าและหลังและช่องว่าง: trim( $domain, " \t\n\r\0\x0B." ) !== $domain
  • สมมติว่าโดเมนจะมีการย่อยอย่างน้อยสอง: $subs = explode( '.', $domain );แล้ว
    • 2 > count( $subs )
    • trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
    • !preg_match('/^[a-z0-9-]+$/i', $sub )

ที่มา: WP Core v4.0

ตัวกรอง & การตรวจสอบที่กำหนดเอง

กรณีดังกล่าวข้างต้นทั้งหมดจะทำให้เกิดis_email()การกลับเท็จ ผลที่ได้คือตัวกรองที่สามารถ (โทรกลับสามารถแนบ) และตัวกรองจะมีสามข้อโต้แย้งที่อาร์กิวเมนต์สุดท้ายคือเหตุผล ตัวอย่าง:

return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );

ซึ่งหมายความว่าคุณสามารถแทนที่ผลลัพธ์ที่ส่งคืนโดยการตรวจสอบเฉพาะ

สิ่งนี้อนุญาตให้คุณเพิ่มการตรวจสอบพิเศษตัวอย่างเช่นอนุญาตให้ Umlaut-domains ชิ้นส่วนโดเมน TLD-only ฯลฯ

ข้อสรุป

WordPress ปลอดภัยสำหรับกรณีส่วนใหญ่ แต่มีข้อ จำกัด มากขึ้นเนื่องจากเซิร์ฟเวอร์อีเมลต้องเป็นไปตามมาตรฐาน RFC โปรดทราบว่าเมลเซิร์ฟเวอร์ทุกเครื่องจะไม่สอดคล้องกับแนวทาง RF 6531

แก้ไข

ตลก sidefact: มีสองฟังก์ชั่นที่เกี่ยวข้องด้านในเป็น~/wp-includes/formatting: และis_email() sanitize_email()พวกมันฟังก์ชั่นเดียวกัน ฉันไม่รู้ว่าทำไมบางคนตัดสินใจว่ามันเป็นความคิดที่ดีที่จะคัดลอกเนื้อหาของฟังก์ชั่นจากที่หนึ่งไปยังอีกที่หนึ่งแทนที่จะเพียงแค่เพิ่มหนึ่งเป็นโทรกลับไปที่ตัวกรองอื่น ๆ ให้ ในฐานะที่เป็นตั้งแต่ v0.71และตั้งแต่ v1.5เหมือนกันผมเองจะใช้ในภายหลังที่คุณได้รับการทำความสะอาดสตริง โปรดทราบว่าแม้ระบุว่าไม่สอดคล้องกับ RFCis_email() sanitize_email() is_email()


ในทางทฤษฎีแล้วจะมีที่อยู่อีเมลที่ถูกต้องตาม RFC 6531 แต่ WordPress จะถือว่าไม่ถูกต้อง?
henrywright

บางคนก็ใช่ ตัวอย่างเช่นโดเมน TLD เท่านั้น, โดเมน umlaut ฯลฯ ตามที่คุณสามารถอ่านในย่อหน้าสุดท้ายก่อนที่จะสรุปในคำตอบ โปรดอ่านคำตอบอีกครั้ง ฉันรู้ว่ามันเยอะที่จะพันหัวคุณ แต่มันก็คุ้มค่า
ไกเซอร์

1
ฉันอ่านมันมาแล้วสองครั้งเพราะนี่คือสิ่งที่ควรค่าแก่การเข้าใจ! ขอบคุณสำหรับคำตอบที่มีรายละเอียดเช่น :)
henrywright

2

ฆ่าเชื้อทุกสิ่ง!

หนึ่งในกฎความปลอดภัยที่สำคัญคือการไม่ไว้วางใจอินพุตจากผู้ใช้ โดยทั่วไปฉันไม่สนใจเกี่ยวกับการใช้งาน is_email () หรือฟังก์ชั่นเฉพาะอื่น ๆ หรือถ้าฟังก์ชั่นนั้นทำอะไรที่เป็นอันตรายกับสิ่งที่ฉันให้ บางทีการใช้งานอาจมีการเปลี่ยนแปลงในบางวัน ใครจะรู้. ฉันต้องคิดว่ามันสามารถถูกบุกรุกได้ ข้อสันนิษฐานที่ควรจะเป็นคือการป้อนข้อมูลผู้ใช้เป็นปฏิปักษ์อย่างแข็งขันเพิ่มขึ้นเป็นสองเท่าดังนั้นในที่สุดสิ่งใดก็ตามที่กำหนดไว้สำหรับฐานข้อมูลและทำให้ผู้ใช้ทุกบิตของผู้ใช้ก่อนที่จะส่งไปยังฟังก์ชั่นบางอย่าง นี่เป็นแค่สุขอนามัยความปลอดภัยทั่วไปที่ดี


ฉันคิดว่าคุณโดนตะปูหัวเมื่อคุณบอกว่าคุณไม่รู้ว่าการใช้งานจะเปลี่ยนไปหรือไม่ มันอาจจะไม่เป็นไรที่จะไม่ฆ่าเชื้อในตอนนี้ แต่ใครจะรู้ว่าจะมีการเปลี่ยนแปลงในภายหลัง
henrywright
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.