Reflected Cross-Site Scripting (XSS) Vulnerability in Pixel Cat
One of the changelog entries for a recent version of the WordPress plugin Pixel Cat is “Fix possible XSS vector reported.” We checked on that and found that contrary to the claim, it was not a “possible” issue, but a reflected cross-site scripting (XSS) vulnerability.
The change made replaced these lines in the previous version:
84 85 86 | $review_url = add_query_arg( array( 'fca_pc_review_notice' => 'review', 'fca_pc_nonce' => $nonce ) ); $postpone_url = add_query_arg( array( 'fca_pc_review_notice' => 'later', 'fca_pc_nonce' => $nonce ) ); $forever_dismiss_url = add_query_arg( array( 'fca_pc_review_notice' => 'dismiss', 'fca_pc_nonce' => $nonce ) ); |
With lines that added escaping using esc_url():
$review_url = esc_url( add_query_arg( array( 'fca_pc_review_notice' => 'review', 'fca_pc_nonce' => $nonce ) ) ); $postpone_url = esc_url( add_query_arg( array( 'fca_pc_review_notice' => 'later', 'fca_pc_nonce' => $nonce ) ) ); $forever_dismiss_url = esc_url( add_query_arg( array( 'fca_pc_review_notice' => 'dismiss', 'fca_pc_nonce' => $nonce ) ) );
Those values were and still are output without additional escaping:
92 93 94 | echo "<a href='$review_url' class='button button-primary' style='margin-top: 2px;'>" . __( 'Leave review', 'facebook-conversion-pixel' ) . "</a> "; echo "<a style='position: relative; top: 10px; left: 7px;' href='$postpone_url' >" . __( 'Maybe later', 'facebook-conversion-pixel' ) . "</a> "; echo "<a style='position: relative; top: 10px; left: 16px;' href='$forever_dismiss_url' >" . __( 'No thank you', 'facebook-conversion-pixel' ) . "</a> "; |
As confirmed with the proof of concept below, the previous lack of any escaping permitted reflected XSS to occur. That could only occur if the plugin’s admin notice about leaving a review was being shown on admin pages.
We checked for any additional issues with lack of escaping with usage of add_query_arg() and remove_query_arg(). We found that the only other usage already had escaping in place.
Proof of Concept
The following proof of concept will cause the number 1 to be shown in an alert box, when logged in to WordPress and the plugin’s admin notice about leaving a review is shown.
Replace “[path to WordPress]” with the location of WordPress.
http://[path to WordPress]/wp-admin/'><script>alert(1);</script>