Tôi có nên vệ sinh một địa chỉ email trước khi chuyển nó đến hàm is_email () không?


13

Tôi đang sử dụng is_email()để kiểm tra xem địa chỉ email do người dùng cung cấp có hợp lệ không. Ví dụ:

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

Theo hiểu biết tốt nhất của tôi, không có gì trong chức năng này ghi thông tin vào cơ sở dữ liệu. Tôi có nên vệ sinh $emailtrước khi chuyển nó vào chức năng không?


Kaiser, cảm ơn đã chỉnh sửa. Đó thực sự là vấn đề đối với tôi nhưng tôi chắc chắn rằng hầu hết độc giả ở đây sẽ sử dụng z :)
henrywright

Câu trả lời:


5

Nhìn vào is_email()chức năng trên trac, có vẻ như bạn không cần phải sanatizie vì đây chỉ là thử nghiệm chuỗi. Tôi thậm chí sẽ đi xa hơn để nói rằng nếu chức năng này trở lại đúng, bạn sẽ không cần phải vệ sinh nó trước khi gửi nó vào cơ sở dữ liệu.


Suy nghĩ của tôi chính xác về kiểm tra chuỗi. Tôi nghĩ rằng tôi vẫn sẽ vệ sinh trước khi gửi tới db, có lẽ bạn đúng là không cần thiết, nhưng tôi là một kẻ phá hoại lo lắng khi nói đến những điều này :)
henrywright

Đúng, an toàn tốt hơn xin lỗi và chi phí vệ sinh sẽ hoàn toàn không được chú ý.
Howdy_McGee

18

Lõi WordPress và PHP

Các is_email()chức năng Nguồn là một WordPress thực hiện điển hình và không hoạt động hoàn toàn với những gì các RFC 6531 cho phép. Một lý do có thể là, FILTER_VALIDATE_EMAILhằng số PHP mặc định filter_var()không tốt hơn nhiều trong việc xác thực một cái gì đó theo hướng dẫn của Lực lượng đặc nhiệm kỹ thuật Internet (IETF®) .

Tiêu chuẩn

Điểm đáng chú ý là RFC 6531 cho phép "các ký tự Unicode vượt ra ngoài phạm vi ASCII" . Cụ thể là những phần này (đối với phần địa phương - trước phần @):

  • Chữ in hoa và chữ thường viết hoa (a, z, A, Z) (ASCII: 65 Tiết90, 97 Đổi22)
  • Chữ số 0thành 9(ASCII: 48 Ném57)
  • Những nhân vật đặc biệt: ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • Ký tự .(dấu chấm, dấu chấm, dấu chấm hết) (ASCII: 46) miễn là nó không phải là ký tự đầu tiên hoặc cuối cùng và cũng được cung cấp rằng nó không xuất hiện liên tiếp (ví dụ: John..Doe@example.comkhông được phép).
  • Các ký tự đặc biệt được phép với các hạn chế. Họ đang:
    • Không gian và "(),:;<>@[\](ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91 Phản93)
    • Các hạn chế đối với các ký tự đặc biệt là chúng chỉ phải được sử dụng khi được chứa giữa các dấu ngoặc kép và 2 trong số chúng (dấu gạch chéo ngược \ và dấu ngoặc kép "(ASCII: 92, 34)) cũng phải được đặt trước dấu gạch chéo ngược \(ví dụ "\\""\"") .
  • Nhận xét được cho phép với dấu ngoặc đơn ở cuối phần địa phương; ví dụ john.smith(comment)@example.com(comment)john.smith@example.comcả hai đều tương đương "john.smith@example.com", nhưng john.(comment)smith@example.comsẽ không hợp lệ.
  • Các ký tự quốc tế ở trên U+007F, được mã hóa dưới dạng UTF-8, được RFC 6531 cho phép, mặc dù các hệ thống thư có thể hạn chế sử dụng các ký tự nào khi gán các phần cục bộ.

và cho phần toàn cầu / tên miền:

Phần tên miền của một địa chỉ email phải tuân thủ các nguyên tắc nghiêm ngặt: nó phải phù hợp với các yêu cầu đối với tên máy chủ, bao gồm các chữ cái, chữ số, dấu gạch nối và dấu chấm. Ngoài ra, phần tên miền có thể là một địa chỉ IP theo nghĩa đen, được bao quanh bởi dấu ngoặc vuông, chẳng hạn như jsmith@[192.168.2.1]hoặc jsmith@[IPv6:2001:db8::1][Tiết]

Nguồn: Wikipedia

Điều gì là hợp lệ?

Điều này có thể dẫn đến các địa chỉ email lạ, nhưng hợp lệ như sau:

  • 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

Nguồn: php.net / tác giả gt@kani.hu - ví dụ được cố định bởi tác giả của bài đăng này

Hạn mức

Ngoài ra còn có giới hạn độ dài cục bộ & tên miền:

Định dạng của địa chỉ email là local-part@domainnơi phần cục bộ có thể dài tối đa 64 ký tựtên miền có thể có tối đa 253 ký tự - nhưng tối đa 256 ký tự của đường dẫn chuyển tiếp hoặc ngược lại giới hạn toàn bộ địa chỉ email dài không quá 254 ký tự . [2] Các định nghĩa chính thức nằm trong RFC 5322 (phần 3.2.3 và 3.4.1) và RFC 5321 - với dạng dễ đọc hơn được đưa ra trong RFC 3696 [3] thông tin và các lỗi liên quan .

Nguồn: Wikipedia

Hạn chế WordPress

Và đây là những gì WordPress kiểm tra:

  • Kiểm tra độ dài tối thiểu của email có thể là: strlen( $email ) < 3
  • Kiểm tra ký tự @ sau vị trí đầu tiên: strpos( $email, '@', 1 ) === false
  • Kiểm tra các ký tự không hợp lệ: !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
  • Kiểm tra trình tự các giai đoạn: preg_match( '/\.{2,}/', $domain )
  • Kiểm tra các khoảng thời gian hàng đầu và dấu và khoảng trắng: trim( $domain, " \t\n\r\0\x0B." ) !== $domain
  • Giả sử tên miền sẽ có ít nhất hai mục con: $subs = explode( '.', $domain );và sau đó
    • 2 > count( $subs )
    • trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
    • !preg_match('/^[a-z0-9-]+$/i', $sub )

Nguồn: WP Core v4.0

Bộ lọc & xác nhận tùy chỉnh

Tất cả các trường hợp được đề cập ở trên sẽ kích hoạt is_email()để trả về false. Kết quả là có khả năng lọc (có thể đính kèm một cuộc gọi lại) và bộ lọc sẽ có ba đối số, trong đó đối số cuối cùng là lý do. Thí dụ:

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

có nghĩa là bạn có thể ghi đè kết quả được trả về bằng các kiểm tra cụ thể.

Điều này cho phép bạn thêm các kiểm tra đặc biệt, ví dụ để cho phép các tên miền Umlaut, các phần miền chỉ có TLD, v.v.

Phần kết luận

WordPress an toàn cho hầu hết các trường hợp, nhưng hạn chế hơn vì các máy chủ thư thực sự phải tuân thủ RFC. Hãy nhớ rằng không phải mọi máy chủ thư sẽ phù hợp với hướng dẫn RF 6531.

Biên tập

Sidefact vui: Có hai chức năng liên quan bên trong ~/wp-includes/formatting: is_email()sanitize_email(). Họ thực tế là cùng một chức năng. Tôi không biết tại sao ai đó quyết định rằng sẽ sao chép nội dung chức năng từ cái này sang cái khác thay vì chỉ thêm cái này như gọi lại vào các bộ lọc mà cái kia cung cấp. Vì v0.71vì v1.5 là như nhau, cá nhân tôi sẽ sử dụng sau này khi bạn nhận được một chuỗi được làm sạch. Lưu ý rằng thậm chí nói rằng nó không tuân thủ RFC.is_email() sanitize_email() is_email()


Vì vậy, theo lý thuyết, sẽ có những địa chỉ email hoàn toàn hợp lệ theo RFC 6531 nhưng những địa chỉ này sẽ bị WordPress coi là không hợp lệ?
henrywright

Một số có. Ví dụ: tên miền chỉ TLD, tên miền umlaut, v.v. như bạn có thể đọc trong đoạn cuối trước khi kết luận trong câu trả lời. Xin vui lòng đọc câu trả lời một lần nữa. Tôi biết sẽ rất nhiều khi quấn đầu xung quanh, nhưng nó đáng giá.
kaiser

1
Tôi thực sự đã đọc nó hai lần vì đây là điều đáng để hiểu! Cảm ơn câu trả lời chi tiết như vậy :)
henrywright

2

Vệ sinh tất cả mọi thứ!

Một trong những quy tắc bảo mật chính là không bao giờ tin vào đầu vào từ người dùng. Nói chung, tôi không quan tâm đến việc triển khai is_email () hoặc bất kỳ chức năng cụ thể nào khác, hoặc nếu chức năng đó làm bất cứ điều gì nguy hiểm với những gì tôi cung cấp cho nó. Có thể việc thực hiện sẽ thay đổi một ngày nào đó. Ai biết. Tôi phải cho rằng nó có thể bị xâm phạm. Giả định phải luôn luôn là đầu vào của người dùng tích cực thù địch, vì vậy, đối với bất kỳ thứ gì cuối cùng sẽ dành cho cơ sở dữ liệu và vệ sinh từng bit đầu vào của người dùng trước khi chuyển nó sang một số chức năng. Đây chỉ là tốt, vệ sinh an ninh chung.


Tôi nghĩ rằng bạn đánh vào đầu đinh khi bạn nói rằng bạn không bao giờ biết nếu việc thực hiện sẽ thay đổi. Có thể không ổn khi không vệ sinh ngay bây giờ, nhưng ai biết nếu điều đó sẽ thay đổi vào một ngày sau đó?
henrywright
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.