Find out how Easy Property Listings removed a major security plugin issue in version 3.4

What a stressful time we’ve just been through which blindsided us and upended our plans, and new extension schedule and major extension updates.

Threw that right out the window.

On Wednesday July 22nd 2019 Easy Property Listings was delisted from the WordPress.org plugin directory.

WHAT! the??? was exactly was going through my head at this time… Next I visited the plugin on WordPress.org and yep, low and behold the statement.

“Your plugin is no longer available for download.”

A cold chill ran down the back of my neck when reading these words.

What did we do?

Thinking, we have no code that is nefarious or below board as you read about apps and social media platforms not caring about user privacy, that is not us… What did we do?

Thankfully WordPress.org have a system in place and after checking my email was a very clear and specific email about exactly what was wrong with Easy Property Listings and more importantly what to do about it to get back into the plugin directory.

Jul 22, 2019, 10:27 AM

Your plugin has had to be temporarily withdrawn from the WordPress.org Plugin Directory due to an exploit.

For the next 60 days, your plugin will simply say that it is no longer available for download. After that time, it will state that it was closed for a security issue.

Plugin Page: https://wordpress.org/plugins/easy-property-listings/

Vulnerability Report: https://www.pluginvulnerabilities.com/2019/07/19/a-hackers-looks-to-be-probing-for-the-wordpress-plugin-easy-property-listings-these-vulnerabilities-might-be-why/

Plugins are closed once we are made aware of any security issues and have verified their exploit-ability. We believe that leaving plugins open would put users at risk if we allowed them to download code that could be exploited, and once an exploit is reported, it is often acted upon by persons nefarious.

Please review the exploit report carefully. If you believe the report is not valid, and that your plugin is secure, please reply to this email to let us know. If the vulnerability is XSS or CSRF related, know that Chrome actually prevents those from working in their browser and you may need to check in Firefox or another browser.

If you find this report to be valid, you must resolve the exploit and update your plugin in our directory in order to have it restored. When you do so, remember to increase the version number of your plugin to reflect the change, this ensuring that your users will be alerted to the update once your plugin is reopened.

Bear in mind, this is NOT a complete security review of your plugin. Once you’ve corrected the listed issue(s), you should perform a top-down review of your entire plugin and look for any and all possible issues. Take the time to make sure you’re in full compliance with the guidelines as well.

Once you’re certain you’ve fixed everything, update your code in SVN and reply to this email. At that time, we will perform a complete security and guideline review, as if you were a new plugin, and either reopen your plugin or report any remaining issues with the code. We require plugins to be safe before we will reopen them.

Please review our documentation on how to use SVN – https://developer.wordpress.org/plugins/wordpress-org/how-to-use-subversion/#best-practices

Your plugin will not be re-opened until it is reviewed, and it won’t be reviewed until you reply to this email and tell us you’ve checked the code in to SVN.

This review process may take a while. Please be patient. We do understand that your plugin is important to you, and we do prioritize security reviews over everything else. Still, it can take us up to 5 business days to give your plugin a complete review.

We will check both your changes and your plugin as a whole, to ensure we didn’t miss anything. You will be required to correct all security issues before we can reopen the plugin. This is because if we found another security issue down the road, we would have to close your plugin again. We feel it’s better for your reputation to have a plugin closed once and fixed rather than multiple times.

Should you, for any reason, find you are unable to update the plugin, please let us know promptly so we can decide on the best course of action to take in order to protect the users. It’s okay if you just can’t fix this or don’t want to.

If you have any queries or need any advice, please let us know.

At least we knew what to do as the site Plugin Vulnerabilities let us know where the specific security was and how to test it once fixed.

We got to work immediately on correcting the issue

This is where the process was a bit less informative. We fixed the immediate issue and submitted the changes for review on the 24th July. The ball was now in the WordPress.org plugin review court.

NOTE: I’m publishing the full emails from WordPress.org in a hope for others to learn from what happened to us. In reality I’m really glad issues were found as we were able to correct them and learn about some new tools that we had no idea were a thing.

Reply on the 26th.

Your plugin has some security issues as well as some minor issues that should be resolved. We will not REQUIRE you to fix the non-security ones right now, but we do strongly encourage you address it as soon as possible.

SECURITY:

## Please sanitize, escape, and validate your POST calls

When you include POST/GET/REQUEST/FILE calls in your plugin, it’s important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.

SANITIZE: Data that is input (either by a user or automatically) must be sanitized. This lessens the possibility of XSS vulnerabilities and MITM attacks where posted data is subverted.

VALIDATE: All data should be validated as much as possible. Even when you sanitize, remember that you don’t want someone putting in ‘dog’ when the only valid values are numbers.

ESCAPE: Data that is output must be escaped properly, so it can’t hijack admin screens. There are many esc_*() functions you can use to make sure you don’t show people the wrong data.

To help you with this, WordPress comes with a number of sanitization and escaping functions. You can read about those here:

* https://developer.wordpress.org/plugins/security/securing-input/
* https://developer.wordpress.org/plugins/security/securing-output/

Remember: You must use the MOST appropriate functions for the context. If you’re sanitizing email, use sanitize_email(), if you’re outputting HTML, use esc_html(), and so on.

Clean everything, check everything, escape everything, and never trust the users to always have input sane data.

Some examples from your plugin:

easy-property-listings/lib/includes/class-epl-meta-boxes.php:324: $epl_date = $_POST[ $field[‘name’] ];
easy-property-listings/lib/includes/class-epl-meta-boxes.php:347: update_post_meta( $post_ID, $field[‘name’], $_POST[ $field[‘name’] ] );
easy-property-listings/lib/includes/admin/admin-functions.php:495: $ver = $_POST[‘upgrade_to’];
easy-property-listings/lib/includes/admin/reports/graphing.php:395: $dates[‘year’] = isset( $_GET[‘year’] ) ? $_GET[‘year’] : date( ‘Y’ );
easy-property-listings/lib/includes/admin/reports/graphing.php:396: $dates[‘year_end’] = isset( $_GET[‘year_end’] )? $_GET[‘year_end’]: date( ‘Y’ );

NON SECURITY

## Including your own CURL code

WordPress comes with an extensive HTTP API that should be used instead of creating your own curl calls. It’s both faster and more extensive. It’ll fall back to curl if it has to, but it’ll use a lot of WordPress’ native functionality first.

HTTP API

Some examples from your plugin:

easy-property-listings/lib/includes/functions.php:97:
$response = curl_exec($ch);

## Including Libraries Already In Core

Your plugin has included a copy of a library that WordPress already includes.

WordPress includes a number of useful libraries, such as jQuery, Atom Lib, SimplePie, PHPMailer, PHPass, and more. For security and stability reasons, plugins may not include those libraries in their own code, but instead must use the versions of those libraries packaged with WordPress.

While we do not YET have a decent public facing page to list all these libraries, we do have a list here: https://meta.trac.wordpress.org/browser/sites/trunk/api.wordpress.org/public_html/core/credits/wp-52.php#L443

* easy-property-listings/lib/assets/js/jquery.ui.touch-punch.min.js

Back to work

Alright so we got back to work on some more fixes and submitted 3.3.5 on the 30th. It was a lot of work to do by the team here. We dropped everything else and laser focused on resolving these other issues.

Basically our plugin was flagged for 1 issue, however fixing that was not enough to get the plugin back into the directory.

Personally I see the thought process behind this with the WordPrss.org team however this means that we are unable to release a fix that you could download until we got everything perfect…

The issue I have with this is even though we patched X you were not able to download that patch and there was nothing we could do until we went through the process of fixing every single line of code in the plugin manually.

We tackled the issues in the previous email and submitted 3.3.5

I’ve been considering the timezone issues as we are in Perth and a lot of the WordPress.org team are all over the world but pretty much North American timezones.

My reply on the 26th.

Thank you for reviewing the plugin, we’ve reviewed all code and patched, edited and reviewed it, we even patched the non security issues also in the TRUNK and TAG 3.3.5

Really appreciate the guidance with your code snippets and thank you for checking our security issues.

Here is hoping we patched all issues.

We await your review and hopefully be live again on the WP.org plugin directory.

 

Reply July 31st

You still have some sanitization issues

easy-property-listings/lib/includes/functions.php:2092:
$post_type = isset($_GET[‘view’]) ? $_GET[‘view’] : ‘property’;
easy-property-listings/lib/includes/functions.php:2108:
$range
= isset($_GET[‘range’])?$_GET[‘range’]:’other’;

easy-property-listings/lib/includes/admin/contacts/contact-actions.php:560:
epl_update_contact_tag_bgcolor($_POST[‘term_id’],$_POST[‘bg’]);

And so on.

HMMMMMMMMMM, and so on….

That line got me thinking. “Are we going to fix one thing and continue to get a reply saying something else is not correct every time we submit a new build” Our plugin is frigging huge and this will be impossible and leave all the current sites with a flaw.

My reply July 31st

Alright my developer used grep to search the code and picked up and corrected several more GET REQUEST POST issues and sanitised them.

I’ve JUST pushed the TRUNK so we can fix and version with your approval.

Are you able to provide any more detail on additional fixes we need to do?

Thanks

Fingers crossed we get some guidance to help us.

Reply 1st August

We recommend a PHP Code Sniffer scan of your code, using the WordPress Coding Standards, in order to help you determine the overall security and quality of your code.

Note: No tool can promise or deliver a 100% security check of your code.

https://github.com/squizlabs/PHP_CodeSniffer
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards

You need to walk through function save_meta_box( $post_ID )

Looking there, you have a LOT of non-sanitized code:

$epl_meta_box_ids = ”;
if(isset($_POST[‘epl_meta_box_ids’])) {
$epl_meta_box_ids = $_POST[‘epl_meta_box_ids’];
}

and

$_POST[ $field[‘name’] ] = $epl_date;

and

if( isset($_POST[ $field[‘name’] ]) ){
$meta_value = $_POST[ $field[‘name’] ];
update_post_meta( $post_ID, $field[‘name’], $meta_value );
}

Also you don’t need to make this check:

if( function_exists( ‘sanitize_textarea_field’ ) ){
$_POST[ $field[‘name’] ] = sanitize_textarea_field( $_POST[ $field[‘name’] ] );
}

There’s no point in the if-exists check for a WordPress CORE function. If that doesn’t exist, there’s so much wrong your plugin probably won’t even run.

But also re-saving as POST data is a poor development choice.

$sanitize_field_name = sanitize_textarea_field( $_POST[ $field[‘name’] ] );

Excellent! There are tools we can use to help us!

FINALLY! a response and some help from the WordPress.org plugin team. Problem is I had to ask and I’m sure that there are many other plugin developers who do not know about the tools in the reply from the plugin team.

I’m assuming that the replies are from different people and this particular person cares about us!

Yipee we have something to help us.

My Reply 1st August

Well…

Haven’t you just opened up a can of worms for us.

Thankfully so, after the installation of the tools below….

WHERE HAS THIS BEEN !!! Wow what a tool!

Amazing thanks for the share,

Working on our code, this will take us days but we will be better for it and have a better product in the WP.org directory.

Again thanks for chucking the golden spanned in the works

100% not sarcasm, what a tool set to make me and my team better coders

Will let you know once the TRUNK is ready “really ready”

Thanks

With the new tool in hand we were ready

OH Shit.

This is going to take time to resolve and as we are a small team servicing 7,000+ websites around the world we are going to need to break the work down and I had to put my coding hands back in the game.

With this new command line tool we were able to scan files for issues and flag them for fixing.

I worked on the overall simpler Code Standards changes while our lead developer, Prince worked on the security fixes and translation issues.

Through this process we learned about a new coding tool called PHPStorm which we now use as it has extensive capabilities to scan code for issues and apply numerous fixes and helps automate internal code documentation.

So I decided that we were to fix everything even internal documentation issues and apply WordPress Code Standards across every file and line in Easy Property Listings.

Once we got the all clear from our extensive testing we submitted to WordPress.org version 3.4 on August 13th.

My reply and submission August 13th

We have pushed the lates build to TRUNK for your review.

Used
phpcs
phpcbf
phpcs –standard:WordPress
Processed what we could with phpStorm
Implemented a very large number of esc_html__ esc_attr (many others with _e __ as required by the functions.
Edited every file in the plugin, renamed files to hit WP standards naming, huge changes and for the better.
please help us get the plugin back into the directory so specifics on additional security fixes would be of great help now that we really have edited everything in the plugin.
Again thanks for the phpcs tool suggestions was a great help,

We worked day and night to get this done.

I was expecting a reply with some more changes BUT due to the huge changes and checks we made and having these new tools at our disposal the email we got was:

Reply Aug 13, 2019

Your plugin has been re-listed in the directory.

Be advised: This does not offer any assurance that your plugin is free of all security issues or all guideline violations.

While we do our best to spot everything (just like you do) we’re human. We may have missed things, being not as familiar as you are with your own code.

We strongly recommend you take the time to perform as through a review as you can of your own work. This should be your top priority as once a plugin is closed, many people will think it is because it was insecure, even if it wasn’t. That means your plugin becomes a target for hackers. There isn’t a good way to avoid this assumption.

You may notice your stats are out of sync for the next while. Since our systems are heavily cached, this can take a while for all the servers and APIs to catch up. Please don’t panic. They’ll reset properly given enough time, and there’s nothing we can do to speed it up.

As long as your plugin is open, it’ll get sorted out eventually. Don’t panic.

Fingers crossed.

Joy! Pure joy reading that email and a feeling of relief came over me and the team.

We did it, the spanner has been removed from Easy Property Listings and we can now move forward and get back on track.

Due to the extensive changes in 3.4 we knew that we would need to fix issues caused by the new security functions in place.

We are not the only plugin with security issues

There seems to be a major push into checking plugins and themes for security issue recently which is actually really great.

Means we as developers can learn about how to write more secure code and ensure our users are as protected as possible with their WordPress websites.

The iThemes team have been publishing WordPress Vulnerability blog posts in August where we were included in part 2.

Much bigger plugins than ours have also had security issues patched.

See the following blog posts from iThemes the makers of iThemes Builder Theme, BackupBuddy and Security Pro.

Ensure your real estate website is secure

We’ve done extensive work on Easy Property Listings 3.4 and encourage you to update to the latest version as soon as possible to avoid any site security issues.

Reach out to us if you are concerned by opening a support ticket, we are here to help you make your real estate website the best it can be.

Full Change Logs

3.4.5 September 5, 2019

  • Fix: Editor custom field type stripping html.
  • Fix: Remove strict type for checkbox & select multiple field types which prevented saving number type array options.

3.4.4 September 4, 2019

  • Fix: Checkbox array options not saving correctly in extensions settings.
  • Fix: Removed default template check for loop and single templates as this caused incorrect templates to load in some cases.

3.4.3 August 29, 2019

  • Fix: Displaying of Geo and Unique ID columns in admin.

3.4.2 August 27, 2019

  • Fix: Issue when using WordPress default pagination, output corrected.

3.4.1 August 25, 2019

  • New: Hidden meta fields for currency support, and floor plan modified date time.
  • Tweak: Support for meta fields file type to support as an array of data.
  • Tweak: Allow embeds and scripts in meta fields like floor plans and energy certificates to support an array of data which is handy during data import.
  • Tweak: Corrected undefined variables in widgets since WordPress 5.2.2.
  • Tweak: Admin contacts added wrapper classes to contact values.
  • Fix: Currency support for search widget price sliders.
  • Fix: Commercial search fix, widget select type field fix: not saving.
  • Fix: Agent search suggestions in admin.
  • Fix: Reports graph date display issues.
  • Fix: Search templates will no longer ignore custom fields added using filters.
  • Fix: When adding dynamic content to a listing using the WordPress editor default WordPress behaviour is restored allowing page builder content to display correctly.

3.4 August 16, 2019

  • MAJOR Security Update Release. Important to update to the latest version to protect your website. Easy Property Listings has been reviewed and approved by the WordPress plugin team.
  • WordPress standards coding applied to all plugin files and code.
  • This is a critical update to Easy Property Listings plugin that is focused on security enhancements. Update you site to this version.
  • New: Reset settings to default values tool page added viewable with &dev=true added to tools page URL.
  • New: Added autocomplete option to meta-fields array.
  • Tweak: Internal code documentation enhanced.
  • Tweak: Admin, structure, style, enhanced, legacy CSS optimisations.
  • Tweak: JS enhancements, improvements and optimisations.
  • Tweak: Removed depreciated author meta compatibility file.
  • Tweak: Removed depreciated listing meta compatibility file.
  • Tweak: Removed depreciated extensions compatibility file.
  • Tweak: Ability to arrange EPL – Search Widget options dashboard field order.
  • Tweak: Wording alteration for Inspection Times – removed (one per line).
  • Tweak: Removed subscriber user type from Dashboard filtering by User.
  • Tweak: Now using WordPress jQuery touch punch JS script.
  • Tweak: Removed cURL php requirement and instead use WordPress helper function.
  • Tweak: Additional CSS classes added to SVG icons.
  • Tweak: Fix bath and car svg wrapper class name.
  • Tweak: Author box will no longer display bio tab is user bio is empty.
  • Fix: Minimised scripts and css in admin areas to EPL pages.
  • Fix: Versioning added to epl js scripts.
  • Fix: Upgrade database on new installs message no longer displaying as no action is required.
  • Fix: Business listing type pricing.
  • Fix: Translation strings corrected in several places across the entire plugin. Internal translation guides added.
  • Fix: jQuery UI CSS now loading minified version in production mode.
  • Fix: [listing_element] shortcode will now display shortcode values when using frontend GUI builder.
  • Fix: Loading custom CSS using the style-single.css now works correctly.
  • Fix: XSS security flaw.
  • Important Security Update.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.