Skip to content

Instantly share code, notes, and snippets.

Last active March 21, 2024 14:24
Show Gist options
  • Save Xib3rR4dAr/561ac3c17b92cb55d3032504a076fa4b to your computer and use it in GitHub Desktop.
Save Xib3rR4dAr/561ac3c17b92cb55d3032504a076fa4b to your computer and use it in GitHub Desktop.
WP Plugin Permalink Manager <= Multiple Reflected XSS
Copy link

Xib3rR4dAr commented Mar 15, 2024

Stored XSS in permalink-manager-pro

Reproduction Steps:

  1. Login as Editor Author or Author+ user
  2. Create a new post and publish
  3. Then while editing post, from right tab select Post > Permalink Manager > Manage Redirects > Redirect this page to external URL'</textarea><script>eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41,59))</script>

(Crafted payload triggers in attribute context as well as textarea context)
4. Click Save Permalink
XSS will trigger instantly (Self XSS), Stored XSS will also trigger when admin user visits:
Tools > Permalink Manager > Debug
which is:

Copy link

Hi @Xib3rR4dAr,

Other XSS present in permalink-manager-pro but not in permalink-manager:

Login as any user e.g subscriber then visit following to trigger XSS:[a<svg%20onload%3dalert('XSS')>]=1

From frontend, POST requests are sent with action=pm_detect_duplicates but POST can be converted to GET request also since $_REQUEST is used. Converting to GET has advantage that XSS can be triggered via redirection also.

File: wp-content\plugins\permalink-manager-pro\includes\core\permalink-manager-actions.php
719: function ajax_detect_duplicates( $uri = null, $element_id = null ) {
720: $duplicate_alert = __( "Permalink is already in use, please select another one!", "permalink-manager" );
722: if ( ! empty( $_REQUEST['custom_uris'] ) ) {
723: // Sanitize the array
724: $custom_uris = Permalink_Manager_Helper_Functions::sanitize_array( $_REQUEST['custom_uris'] );
725: $duplicates_array = array();
727: // Check each URI
728: foreach ( $custom_uris as $element_id => $uri ) {
729: $duplicates_array[ $element_id ] = Permalink_Manager_Admin_Functions::is_uri_duplicated( $uri, $element_id ) ? $duplicate_alert : 0;
730: }
732: // Convert the output to JSON and stop the function
733: echo json_encode( $duplicates_array );
734: } else if ( ! empty( $_REQUEST['custom_uri'] ) && ! empty( $_REQUEST['element_id'] ) ) {
735: $is_duplicated = Permalink_Manager_Admin_Functions::is_uri_duplicated( $uri, $element_id );
737: echo ( $is_duplicated ) ? $duplicate_alert : 0;
738: }
740: die();
741: }

$element_id which contains XSS is not sanitized properly, while only numbers should have been allowed in it. Also, remove Debug SQL query part from code.

This particular issue was already patched in version (the nulled version of the plugin available on Internet for some does not contain the patch).

Please contact me via email if you need a valid license key to download the untouched plugin's ZIP package.

Copy link

Hi @maciejbis, thanks for correction. I've updated the gist now. I've mailed you for the license and truly appreciate your help in providing with untouched plugin's ZIP package.

Copy link

Xib3rR4dAr commented Mar 17, 2024

Admin Self XSS: (Permalink Manager Pro)

  1. Login as administrator user
  2. Visit /wp-admin/tools.php?page=permalink-manager&section=settings#licence
  3. Paste '" autofocus onfocus=alert(2) a in Licence key input field
  4. XSS will trigger when Save settings is clicked (note that XSS won't trigger when page is reloaded)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment