Tại sao thoát nếu the_content không?


8

Hàm tích hợp the_contentchạy qua một số bộ lọc, nhưng không thoát đầu ra. Nó sẽ rất khó để làm điều đó, vì HTML và thậm chí một số tập lệnh phải được cho phép thông qua.

Khi xuất ra, the_content dường như chạy qua các bộ lọc này (kể từ 5.0):

add_filter( 'the_content', 'do_blocks', 9 );
add_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', 'convert_smilies', 20 );
add_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'shortcode_unautop' );
add_filter( 'the_content', 'prepend_attachment' );
add_filter( 'the_content', 'wp_make_content_images_responsive' );

(and)

add_filter( 'the_content', 'capital_P_dangit' );
add_filter( 'the_content', 'do_shortcode' );

Nó cũng thực hiện một chuỗi thay thế đơn giản:

$content = str_replace( ']]>', ']]>', $content );

Và sau đó get_the_content thực hiện một chút xử lý liên quan đến liên kết "thêm" và một lỗi với ngoại ngữ.

Không ai trong số đó ngăn chặn XSS script, phải không?

Khi lưu, dữ liệu được khử trùng thông qua wp_kses_post. Nhưng vì đây là một quá trình tốn kém, tôi hiểu tại sao nó không được sử dụng trên đầu ra.

Nguyên tắc nhỏ cho việc thoát khỏi WordPress là mọi thứ cần phải được thoát, bất kể vệ sinh đầu vào và gần đây nhất có thể. Tôi đã đọc một số bài báo nói điều này, bởi vì cơ sở dữ liệu không được coi là một nguồn đáng tin cậy.

Nhưng vì những lý do trên, the_content không tuân theo điều đó. Cũng không làm các chủ đề cốt lõi (ví dụ TwentyNineteen) thêm thoát thoát trên đầu ra.

Vậy ... tại sao nó lại giúp mọi thứ trốn thoát? Nếu tôi là một hacker có quyền truy cập vào cơ sở dữ liệu, tôi sẽ không thêm mã của mình vào nội dung của bài viết chứ?


Bạn đã quênwp_kses_post
Tom J Nowell

Nó chạy qua wp_kses_post trên đầu ra? Ở đâu?
kế

Câu trả lời:


10

Nếu tôi là một hacker có quyền truy cập vào cơ sở dữ liệu, tôi sẽ không thêm mã của mình vào nội dung của bài viết chứ?

Nếu bạn có quyền truy cập vào cơ sở dữ liệu, rất có thể bạn đã có đủ quyền truy cập mà việc thoát sẽ không ngăn bạn. Thoát sẽ không giúp bạn nếu bạn đã bị hack. Nó không phải là để. Có những lý do khác để trốn thoát. Hai cái chính mà tôi có thể nghĩ đến là:

Để đối phó với đầu vào không được xác nhận

Nội dung bài đăng WordPress được vệ sinh khi được lưu, nhưng không phải mọi thứ khác. Ví dụ, nội dung được truyền qua chuỗi truy vấn trong URL không được vệ sinh. Không phải là nội dung trong các tập tin dịch, nhất thiết phải. Cả hai đều là nguồn nội dung không liên quan đến trang web bị xâm phạm. Vì vậy, văn bản và nội dung có thể dịch được kéo từ URL cần phải được thoát.

Để ngăn chặn người dùng vô tình phá vỡ đánh dấu

Thoát không chỉ để bảo mật. Bạn cũng cần nó để ngăn người dùng vô tình phá vỡ đánh dấu trang web của họ. Ví dụ: nếu người dùng đặt dấu ngoặc kép hoặc >ký hiệu trong một số nội dung trong plugin của bạn sẽ phá vỡ đánh dấu, thì bạn nên thoát đầu ra đó. Bạn không muốn quá tích cực trong việc vệ sinh đầu vào, bởi vì có những lý do hoàn toàn hợp lệ mà người dùng có thể muốn sử dụng các ký tự đó.


Tiết kiệm không chỉ là về bảo vệ khỏi kẻ xấu. Nó chỉ làm cho phần mềm của chúng tôi bền. Chống lại đầu vào xấu ngẫu nhiên, chống lại đầu vào độc hại hoặc chống lại thời tiết xấu.

Đó là từ hướng dẫn VIP VIP về thoát . Nó có nhiều hơn để nói về vấn đề này, và bạn nên đọc nó.


Cảm ơn bạn, đó là hữu ích. Tôi đã đọc một bài đăng trên VIP về việc trốn thoát và tác giả đã đề cập cụ thể ý tưởng về việc ai đó đã có quyền truy cập vào DB nhưng không phải máy chủ. Tuy nhiên tôi nghĩ rằng lý luận của bạn về điểm đó có ý nghĩa hơn. Và, tôi cho rằng, đôi khi bạn đang thoát khỏi nội dung dễ bị tổn thương khỏi cơ sở dữ liệu ngay cả khi không có ai đó có quyền truy cập hoàn toàn vào cơ sở dữ liệu, tức là thông qua một plugin hoặc thậm chí chỉ là một nhận xét.
kế

9

Tôi thực sự là một kỹ sư tại VIP, người thực hiện nhiều đánh giá mã :) Tôi đánh dấu rất nhiều việc bỏ trốn.

nhưng không thoát đầu ra

Không hoàn toàn, nó không thoát khỏi đầu ra, điều này gây ngạc nhiên cho hầu hết mọi người. Điều này là bởi vì nếu bạn là một quản trị viên siêu hạng, bạn có unfiltered_htmlkhả năng, vì vậy nó không thể thoát khỏi đầu ra. Thay vào đó, nó chạy qua wp_kses_postđầu vào. Lý tưởng nhất là bạn sẽ loại bỏ khả năng đó mặc dù.

Đây là cách thực hiện tại thời điểm hiện tại:

function the_content( $more_link_text = null, $strip_teaser = false ) {
    $content = get_the_content( $more_link_text, $strip_teaser );

    /**
     * Filters the post content.
     *
     * @since 0.71
     *
     * @param string $content Content of the current post.
     */
    $content = apply_filters( 'the_content', $content );
    $content = str_replace( ']]>', ']]>', $content );
    echo $content;
}

Mặt khác, cơ chế lý tưởng để thoát khỏi mọi thứ đi qua the_contentbộ lọc là:

echo apply_filters( 'the_content', wp_kses_post( $content ) );

Bằng cách này, chúng tôi làm cho nội dung an toàn, sau đó chạy nó qua bộ lọc, tránh việc nhúng v.v ... bị loại bỏ.

Vậy tại sao lại trốn thoát

Điểm thoát là tạo HTML hợp lệ, bảo mật được thêm vào mà nó cung cấp chỉ là một hiệu ứng phụ đẹp.

Để ngăn chặn người dùng vô tình phá vỡ đánh dấu

Có nhiều lý do để trốn thoát, nhưng về cơ bản, bạn đang thực thi những kỳ vọng. Lấy mã sau:

<a href="<?=$url?>">

Chúng tôi hy vọng $urlcó chứa một URL phù hợp cho một hrefthuộc tính, nhưng nếu không thì nó là gì? Tại sao lại để nó có cơ hội, hãy thực thi nó:

<a href="<?=esc_url( $url )?>">

Bây giờ luôn luôn là một URL. Sẽ không có vấn đề gì nếu tin tặc đưa hình ảnh vào $urlhoặc nếu người dùng nhập sai trường hoặc có tập lệnh độc hại. Nó sẽ luôn là một URL hợp lệ vì chúng tôi đã nói nó sẽ là một URL. Chắc chắn đó có thể là một URL rất lạ, nhưng nó sẽ luôn đáp ứng kỳ vọng rằng một URL sẽ ở đó. Điều này rất tiện dụng, có thể là để xác thực đánh dấu, để bảo mật, v.v.

Đã nói rằng, trốn thoát không phải là xác nhận, thoát ra không phải là vệ sinh. Đó là những bước riêng biệt xảy ra tại các điểm khác nhau trong vòng đời. Thoát khỏi lực lượng để đáp ứng mong đợi, ngay cả khi nó mang lại cho họ để làm như vậy.

Đôi khi tôi thích nghĩ về việc trốn thoát như một trong những trò chơi của Nhật Bản với bức tường bọt khổng lồ với những đường cắt ra. Các thí sinh phải phù hợp với hình dạng con chó hoặc chúng bị loại bỏ, chỉ với mục đích của chúng tôi có laser và dao xung quanh lỗ. Bất cứ thứ gì còn lại ở cuối sẽ có hình con chó, và nó sẽ không tha thứ và nghiêm ngặt nếu bạn chưa có hình con chó.

Nhớ lại:

  • vệ sinh sớm
  • xác nhận sớm
  • thoát muộn
  • trốn thoát thường xuyên

Bảo mật là một bước gồm nhiều bước, nhiều lớp phòng thủ, thoát là một trong những lớp phòng thủ bên ngoài trên đầu ra. Nó có thể mang mã tấn công vào một trang web bị xâm nhập khiến nó trở nên vô dụng, ngăn chặn các khai thác mở và đảm bảo khách hàng của bạn không phá vỡ một trang web bằng cách đặt các thẻ vào một trường mà họ không nên. Nó không phải là một thay thế cho những thứ khác, và nó là công cụ bảo mật được sử dụng nhiều nhất trong sổ tay nhà phát triển.

Vì sao phải trốn nếu the_contentkhông? Nếu bạn có một trận lụt sắp tới, và 5 lỗ trên tường, nhưng chỉ có thời gian để sửa 3, bạn có nhún vai và sửa không? Hay bạn giảm thiểu rủi ro và giảm khu vực tấn công?

Có lẽ tôi có thể giúp sửa 2 lỗ cuối cùng với đoạn trích này:

add_filter( 'the_content' function( $content ) {
    return wp_kses_post( $content );
}, PHP_INT_MAX + 1 );

Ở đây chúng tôi đặt mức độ ưu tiên thành số cao nhất có thể có trong PHP, sau đó thêm 1 để nó tràn vào số thấp nhất có thể có thể được biểu diễn. Bằng cách này, tất cả các lệnh gọi the_contentsẽ thoát giá trị trước bất kỳ bộ lọc nào khác. Cách này nhúng vv vẫn hoạt động, nhưng người dùng không thể lẻn vào HTML nguy hiểm thông qua cơ sở dữ liệu. Ngoài ra, xem xét loại bỏ unfiltered_htmlkhả năng khỏi tất cả các vai trò


1
Cảm ơn cho quan điểm bổ sung. Tôi thực sự đã đọc bài viết của bạn về chủ đề này trên trang web của bạn và đã tự hỏi nếu bạn có bất cứ điều gì để thêm.
kế vào

4

Điểm thoát là tạo HTML hợp lệ, bảo mật được thêm vào mà nó cung cấp chỉ là một hiệu ứng phụ đẹp.

Các bộ lọc được áp dụng trên nội dung, tạo ra một HTML hợp lệ từ một thứ gì đó là sự pha trộn của HTML và một số văn bản khác có một số cú pháp khác như mã ngắn. Thực tế là một số nội dung đã là HTML hợp lệ ngăn chặn việc áp dụng thoát trên tất cả nội dung đó.

Đối với ksescác chức năng liên quan, bạn không thể áp dụng chúng chủ yếu vì bạn không có đủ ngữ cảnh để biết nên sử dụng chức năng nào. Ví dụ: có thể có một số quy trình sử dụng the_contentbộ lọc để thêm JS vào nội dung bài đăng mà cốt lõi không thể đoán dựa trên những thứ như tác giả bài đăng nếu JS có hợp pháp hay không.

Vậy ... tại sao nó lại giúp mọi thứ trốn thoát? Nếu tôi là một hacker có quyền truy cập vào cơ sở dữ liệu, tôi sẽ không thêm mã của mình vào nội dung của bài viết chứ?

Một lần nữa, thoát là để tạo HTML hợp lệ. Từ một POV bảo mật, không phải là thoát cung cấp bảo mật mà là một mã mà thoát ra sẽ đáng ngờ vì nó có thể dễ khai thác hơn. Ví dụ: cách sử dụng lõi _evà '__` cho các bản dịch nghĩa là bất kỳ ai có thể thuyết phục bạn cài đặt bản dịch không chính thức đều có thể khó phát hiện ra JS trong tệp dịch và hack trang web của bạn. Đây là một ví dụ tốt về "làm những gì tôi nói chứ không phải những gì tôi làm".


Cảm ơn, Mark, cho quan điểm bổ sung.
kế

2

Nếu tôi là một hacker có quyền truy cập vào cơ sở dữ liệu, tôi sẽ không thêm mã của mình vào nội dung của bài viết chứ?

Tôi nghĩ rằng câu hỏi của bạn trả lời chính nó. Nếu bạn là một hacker có quyền truy cập vào db, thì bạn đã có được quyền truy cập mà bạn yêu cầu. Thoát đầu ra không thay đổi điều đó cả.

Lý do để thoát đầu ra là đánh giá dữ liệu không đáng tin cậy để tránh tin tặc có được quyền truy cập đó ngay từ đầu.


Cảm ơn câu trả lời của bạn. Tôi nghĩ rằng tôi đã trở nên quá tập trung vào ý tưởng ngăn chặn một hacker mà tôi đã bỏ lỡ khu rừng để trồng cây.
kế
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.