30 Aug

WordPress Plugin Security Review: DW Mega Menu

For our 32nd security review of a WordPress plugin based on the voting of our customers, we reviewed the plugin DW Mega Menu.

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 1.0.1 of DW Mega Menu. We checked for the following issues during as part of our standard 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 have and continued to be a common source of disclosed vulnerabilities)
  • Security issues with functions accessible through WordPress’ REST API (those have started to be a source of disclosed vulnerabilities)
  • 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 also checked for the following issues as part of looking into whether we should add them to our standard checks:

  • Security issues with functions accessible through the admin_post action
  • Usage of the extract() function


We found three issues with the plugin. We notified the developer of the plugin of the issues a week ago, but we haven’t heard back from them and the plugin has yet to be updated.

The most serious is that with the AJAX accessible function ajax_save() in the file /lib/setting.php it doesn’t check to make sure that only intended WordPress users are able to save changes through that and there isn’t protection against cross-site request forgery (CSRF), which could cause someone logged in to WordPress to save a change without intending it:

public function ajax_save() {
	if ( isset( $_POST['transition'] ) ) {
		update_option( 'dw_megamenu_setting', sanitize_text_field( $_POST['transition'] ) );
		wp_send_json_success( array( $_POST ) );

The value is sanitized using sanitize_text_field(), which limits what an attacker could do with that.

The function dw_megamenu_custom_nav_menu() in the file /lib/nav-menu.php doesn’t sanitize and or validate the user input being saved through it:

if ( isset( $_REQUEST['menu-item-megamenu-type'] ) ) {
	$value = $_REQUEST['menu-item-megamenu-type'][$menu_item_db_id];
	update_post_meta( $menu_item_db_id, '_dw_megamenu_type', $value );
if ( isset( $_REQUEST['menu-item-sicon'] ) ) {
	if ( is_array( $_REQUEST['menu-item-sicon'] ) ) {
		$value = $_REQUEST['menu-item-sicon'][$menu_item_db_id];
		update_post_meta( $menu_item_db_id, '_dw_megamenu_sicon', $value );

The plugin’s .php files don’t have code at the beginning of them to restrict direct access to them. We didn’t see any security issues caused by that, but restricting access to them would insure that there isn’t any issue with that.