Authenticated Local File Inclusion (LFI) Vulnerability in Posts in Page
One of the things we do to make sure our customers have the best data on vulnerabilities in WordPress plugins is to monitor hacking attempts on our websites. Through that we recently came across a request for a file, /wp-content/plugins/posts-in-page/assets/posts_in_page_help_view.php, from the plugin Posts in Page.
Nothing in that file looks like it could be exploited, so it looks like that request was instead probing for usage of the plugin. In looking over the rest of the code of the plugin we did find one vulnerability, that might be of more interest to hackers with the recent exploitation of a vulnerability in WordPress 4.7.0 and 4.7.1 that allowed an attacker to modify posts.
In the file /lib/page_posts.php we first found that it looked like it might be possible for arbitrary files to be included through the following that requires a specified file:
186 187 188 | require ( $file_path = self::has_theme_template() ) ? $file_path // use template file in theme : POSTSPAGE_DIR . '/posts_loop_template.php'; // use default plugin template file |
The function has_theme_template called there looks like this:
164 165 166 167 168 169 170 | protected function has_theme_template() { $template_file = ( $this->args['template'] ) ? get_stylesheet_directory() . '/' . $this->args['template'] // use specified template file : get_stylesheet_directory() . '/posts_loop_template.php'; // use default template file return ( file_exists( $template_file ) ) ? $template_file : false; } |
The value of $this->args[‘template’] in that comes from the “template” attribute of the plugin’s shortcode. There is no restriction on who can use that shortcode or attribute, so contributor-level and above users can cause any file on the website to be included through the use of directory traversal, which is an authenticated local file inclusion (LFI) vulnerability.
For author-level and above users there is a more serious issue as they have ability to upload media through WordPress. It is possible to upload media file that contain PHP code in them. Normally that code would not be able to run because the file extension of the file would not be one that causes the web server to execute it, but including such a file through a vulnerability like this would allow it to run.
Proof of Concept
When logged in as user that can add new posts, adding the following proof of concept to a post’s content will include a file named test.php from the root directory when viewing the resulting post (it will be included even when previewing the post):
[ic_add_posts template='../../../test.php']
Timeline
- February 8, 2016 – Developer notified.
- February 13, 2017 – WordPress.org Plugin Directory notified.
- February 13, 2017 – Vulnerability added to the free data included with our services’s companion plugin.
- February 14, 2017 – Version 1.3.0 released, which fixes vulnerability.
Thank you for your report and your commitment to security in the plugin repository.
You can see the snippets of code mentioned as potentially exploitable in this report on line 186, self::has_theme_template returns a file in the theme directory.
A user cannot upload a file via Media and have it included here. We require the file to be in the theme folder and, if it’s not there, fall back to the posts_loop_template.php file in the plugin’s directory.
Again, it is not possible for even an Admin level user to designate a file outside the template directory. When they try, it fails the file exists test (those lines are testing for the template and if found, use it and if not found, use the default) and the default template is loaded instead.
For anyone wondering about the previous comment, we were subsequently able to clear up the confusion the developer had about how directory traversal works and a new version that fixes the issue should be out soon.
Howdy Folks,
We’ve just released version 1.3.0 which fixes this security vulnerability and cleans up a few other things. It’s available now on WordPress.org at:
https://wordpress.org/plugins/posts-in-page/
Thanks again for your report and your help in keeping WP plugins secure.
Cheers!