19 Feb

WordPress Plugin Security Review: WooCommerce PDF Invoices & Packing Slips

For our 26th security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin WooCommerce PDF Invoices & Packing Slips.

If you are not yet a customer of the service, once you sign up for the service as a paying customer you can start suggesting and voting on plugins to get security reviews. For those already using the service that haven’t already suggested and voted for plugins to receive a review, you can start doing that here. You can use our tool for doing limited automated security checks of plugins to see if plugins you are using have possible issues that would make them good candidates to get a review. You can also order a review of a plugin separately from our service.

The review was done on version 2.2.6 of WooCommerce PDF Invoices & Packing Slips. We checked for the following issues during this review:

  • Insecure file upload handling (this is the cause of the most exploited type of vulnerability, arbitrary file upload)
  • Deserialization of untrusted data
  • Security issues with functions accessible through WordPress’ AJAX functionality (those are a common source of disclosed vulnerabilities these days)
  • Persistent cross-site scripting (XSS) vulnerabilities in the frontend portions of the plugin and in the admin portions accessible to users with the Author role or below
  • Cross-site request forgery (CSRF) vulnerabilities in the admin portion of the plugin
  • SQL injection vulnerabilities (the code that handles requests to the database)
  • Reflected cross-site scripting (XSS) vulnerabilities
  • Security issues with functions accessible through any of the plugin’s shortcodes
  • Security issues with functions accessible through the admin_action action
  • Security issues with functions accessible through the admin_init action
  • Security issues with import/export functionality
  • Security issues with usage of is_admin()
  • Security issues with usage of add_option(), delete_option(), and update_option()
  • Host header injection vulnerabilities
  • Lack of protection against unintended direct access of PHP files
  • Insecure and unwarranted requests to third-party websites
  • Any additional possible issues identified by our Plugin Security Checker


We found one minor vulnerability and a number of other issues where there was room for improvement in the security of the plugin’s code. Several hours after we contacted the developer they committed changes to the plugin’s GitHub project to resolve the issues we identified. Yesterday they released version 2.2.7, which includes those changes.

Cross-Site Request Forgery (CSRF) Vulnerabilities

The functionality that runs when clicking the buttons “Reinstall fonts”, “Remove temporary files”, and “Delete legacy (1.X) settings” on the plugin’s Status page, /wp-admin/admin.php?page=wpo_wcpdf_options_page&tab=debug, was not protected against cross-site request forgery (CSRF). That would have allowed an attacker that could get someone that has access to that page to cause those actions to happen without intending it. The developer has now fixed those by checking for a valid nonce.

Lack of User Input Sanitization

While checking for something else, we found that in one function that user input was not being sanitized when being brought in to the plugin’s code. We didn’t check if that could cause any vulnerabilities outside of what we check for during the review, but sanitizing would be a good idea and the developer has now done that.

Capabilities Check Missing

We found that a couple of AJAX accessible function, which are accessible to anyone logged in WordPress, did not contain a capabilities check to limit who has access to them. There was a check for a valid nonce and the nonce does appear to be accessible to those that should not have access to the functions, but that not be relied as the WordPress documentation states “Nonces should never be relied on for authentication or authorization, access control. Protect your functions using current_user_can(), always assume Nonces can be compromised.” The developer has now updated those to check if the user has the “manage_woocommerce” capability.

Unprepared SQL Statements

We found three SQL statements in the plugin where a variable was used in the statement without the SQL statement being prepared. While it looks like it wasn’t possible to cause SQL injection through those, preparing them would make them more secure, which the developer has now done.

Lack of Protection Against Direct Access to Files

Many of the plugin’s .php files lacked code at the beginning of the files to restrict direct access to them.  We didn’t see anything that could be exploited in the files without the restriction in place. That hasn’t changed for third-party libraries included with the plugin, but with the files that original to the plugin they now all have that (many of them already did).