Skip to main content

Content Injection Vulnerability in WordPress

Content Injection Vulnerability in WordPress

As part of a vulnerability research project for our Sucuri Firewall (WAF), we have been auditing multiple open source projects looking for security issues. While working on WordPress, we discovered was a severe content injection (privilege escalation) vulnerability affecting the REST API. This vulnerability allows an unauthenticated user to modify the content of any post or page within a WordPress site.
We disclosed the vulnerability to the WordPress Security Team who handled it extremely well. They worked closely with us to coordinate the disclosure timeline and get as many hosts and security providers aware and patched before this became public.
A fix for this was silently included on version 4.7.2 along with other less severe issues. This was done intentionally to give everyone time to patch. We are now disclosing the details because we feel there has been enough time for most WordPress users to update their sites.

Are You At Risk?

This privilege escalation vulnerability affects the WordPress REST API that was recently added and enabled by default on WordPress 4.7.0.
One of these REST endpoints allows access (via the API) to view, edit, delete and create posts. Within this particular endpoint, a subtle bug allows visitors to edit any post on the site.
The REST API is enabled by default on all sites using WordPress 4.7.0 or 4.7.1. If your website is on these versions of WordPress then it is currently vulnerable to this bug.

Technical Details

Our journey begins in ./wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

There are a couple of things to notice here. The registered route is designed to populate the ID request parameter with digits. For example, if you are sending a request to /wp-json/wp/v2/posts/1234 – the ID parameter would be set to 1234.
This behavior alone could be a good way to prevent attackers from crafting malicious ID values, but when looking at how the REST API manages access, we quickly discover that it prioritizes $_GET and $_POST values over the ones generated by the route’s regular expression. This makes it possible for an attacker to send a request like: /wp-json/wp/v2/posts/1234?id=12345helloworld  – which would assign 12345helloworld to the ID parameter – which now contains more than just digits.
Investigating further, we had a look at the various callbacks (in the screenshot above) and one of them kept our attention: the update_item and its permission check method update_item_permissions_check.

In short, it passes our alphanumeric ID value directly to the get_post() function. This function validates the request by checking if the post actually exists and whether our user has permission to edit this post. We found this to be a curious way of sanitizing the request. If we send an ID that doesn’t have a corresponding post, we can just pass through the permission check and be allowed to continue executing requests to the update_item method!
Curious about what could cause get_post() to fail at finding a post (other than a non-existent ID), we realized it used the get_instance() static method in wp_posts to grab posts.

As you can see from the code, it would basically fail on any input that isn’t all made of numeric characters – so 123ABC would fail.
For an attacker, this means that WordPress (thinking it’s a user with enough privilege to edit this post) would run the update_item method.
We thought it would make sense to check what this method does.

There is a very subtle, yet important detail in that last screenshot – WordPress casts the ID parameter to an integer before passing it to get_post!
This is an issue because of the way PHP does type comparisons and conversions. For example, one can see that the following snippet would return 123:

This leads to a very dangerous situation where an attacker could submit a request like /wp-json/wp/v2/posts/123?id=456ABC to change the post whose ID is 456!
Due to this type-juggling issue, it is then possible for an attacker to change the content of any post or page on a victim’s site. From there, they can add plugin-specific shortcodes to exploit vulnerabilities (that would otherwise be restricted to contributor roles), infect the site content with an SEO spam campaign, or inject ads, etc.
Depending on the plugins enabled on the site, even PHP code could be executed very easily.

In Conclusion

If you have not enabled automatic updates on your website, update as soon as possible!
This is a serious vulnerability that can be misused in different ways to compromise a vulnerable site. Update now!

https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html

Comments

Post a Comment

Popular posts from this blog

Hướng dẫn cài đặt HĐH Kali Linux trên máy thật

Để cài đặt được HĐH Kali Linux trên máy thật các bạn chỉ cần chuẩn bị như sau: 1- USB >=4GB 2- Phiên bản Linux muốn cài đặt (Tải tại đây) 3- Tải win32 disk imager  (Tải tại đây)    Vậy là đã chuẩn bị xong ! TIẾP TỤC: Bước 1 . Khởi động chương trình UUI. Chọn I Agree. Bước 2 . Cấu hình UUI. Step 1: Select a Linux Distribution from the dropdown to put on your USB : Chọn hệ điều hành cần tạo, bạn chọn Kali Linux. Step 2: Select your Kali*.iso : Chọn file cài cài đặt Kali Linux. Lưu ý: tên file phải bắt đầu bằng Kali và kết thúc bằng .iso . Step 3: Select your USB Flash Drive Letter Only: Chọn thiết bị USB của bạn. Check vào We will format E:\ Drive as Fat32 để format lại USB của bạn. Cấu hình UUI Cảnh báo Format USB hiện lên, bạn chọn Yes để bắt đầu tiến trình. Cảnh báo format, chọn Yes. Tiến trình format và tạo USB Boot Kali Linux bắt đầu. Format và gắn nhãn UUI. Bắt đầu giải nén file .iso. Quá trình giải nén. Bước 3 . Hoàn t...

Hooks in React - How to use it ?

Mới đây, React đã chính thức công bố hooks . Vậy hooks là gì ? Hooks là những hàm cho phép bạn “kết nối” state và lifecycle của React vào các components. Với Hooks bạn có thể sử dụng state và lifecycles mà không cần dùng class. Ví dụ đơn giản cho việc sử dụng hooks useState : - Đầu tiên import thêm useState từ react.  - Ta có 1 function Counter, 2 biến count, setCount và truyền vào cho useState 1 giá trị được gán cho count. - Trong hàm render ta có hiển thị biến count và khi click thì sẽ gọi tới hàm setCount và tăng count lên 1 đơn vị. Qua ví dụ trên ta có thể thấy, việc sử dụng function component kết hợp với hooks hoàn toàn tiện lợi. Nó giúp code trong ngắn gọn và dễ hiểu hơn thay vì ta dùng class và phải setState. Tiếp theo, để có thể dùng được các lifecycles trong function component ta có useEffect . Nó tương tự như các lifecycles componentDidMount , componentDidUpdate , componentWillUnmount . Cách sử dụng useContext trong hooks sẽ như v...

Cách sử dụng Nmap để scan Port trên Kali Linux

Port là gì ? Có rất nhiều lớp trong mô hình mạng nói chung, lớp vận chuyển đóng vai trò cung cấp các thông tin liên lạc giữa các ứng dụng hệ thống với nhau, và lớp này thì được kết nối với Port (Cổng). Một số điều lưu ý mà bạn cần biết về port - Port là một số hiệu ID cho 1 ứng dụng nào đó. - Mỗi ứng dụng chỉ có thể chạy trên một hoặc nhiều port và mang tính độc quyền, không có ứng dụng khác được chạy chung. - Chính vì tính độc quyền nên các ứng dụng có thể chỉnh sửa để cho phép chạy với một port khác. - Port cũng có phân chia làm Internal và External . - Số hiệu từ 1->65535. Một số thuật ngữ mà bạn cần nắm rõ Port: Là một địa chỉ mạng thực hiện bên trong hệ điều hành giúp phân biệt các traffic khác nhau của từng ứng dụng riêng lẻ Internet Sockets: Là một tập tin xác định địa chỉ IP gắn kết với port, nhằm để xử lý dữ liệu như các giao thức. Binding: Là quá trình mà một ứng dụng hoặc dịch vụ (service) sử dụng Internet Sockets để xử lý nhập và xuất các dữ liệu ...