Files

49 lines
2.4 KiB
TOML
Raw Permalink Normal View History

# WP Statistics 13.1.5 -- a WordPress plugin with an unauthenticated SQL injection reached through a hook.
#
# The third WordPress checkout, and the one chosen because it is NOT expected to be found. PMPro's CVE is a
# concatenation inside the function that receives the value; this one crosses WordPress's filter dispatcher,
# which is the shape most plugin data actually travels in. A table that only lists hits teaches nothing about
# where the engine stops.
#
# Verified in the code. At this commit `includes/class-wp-statistics-pages.php:225` reads:
#
# $exist = $wpdb->get_row("SELECT `page_id` FROM ... AND `id` = {$current_page['id']}", ARRAY_A);
#
# and one line below, the SAME value is used correctly:
#
# $wpdb->query($wpdb->prepare("UPDATE ... AND `id` = %d", $current_page['id']));
#
# The value arrives from an unauthenticated REST hit. `Hits::rest_params()` copies every `$_REQUEST` key into
# `$this->rest_hits`; `Hits::set_current_page()` returns `'id' => $this->rest_hits->current_page_id`; and it
# is bound to the sink not by a call but by
#
# add_filter('wp_statistics_current_page', array($this, 'set_current_page')); # hits.php:43
# return apply_filters('wp_statistics_current_page', $current_page); # pages.php:105
#
# Both ends of that edge name the callback with a STRING, so no frontend can draw it. The fix (bc98b414)
# wraps both values in `esc_sql`, which is a modelled sanitizer -- so if the flow were visible at all, the
# pair would separate.
name = "wpstatistics"
url = "https://github.com/wp-statistics/wp-statistics.git"
commit = "ca66e7b89587dce3ee189f1eb42211ad111db4b7"
language = "php"
license = "GPL-2.0"
license_file = "license.txt"
measures = ["detection"]
note = """
The parent of the fix commit bc98b414 ("Sanitize current_page_id & current_page_type in rest request",
2022-02-13), released in the 13.1.x line. Nothing is vendored -- the recipe fetches on request and CI never
does.
"""
[[known]]
id = "CVE-2022-25148"
family = "injection"
weakness = "unauthenticated SQL injection: current_page_id from an unauthenticated REST hit is interpolated into a $wpdb->get_row query, having crossed the wp_statistics_current_page filter"
file = "includes/class-wp-statistics-pages.php"
function = "record"
line = 225
reference = "fixed in bc98b4146afd6f4b29fda1136772dcf1a42f26e6, which applies esc_sql to current_page_type and current_page_id at their source; the vulnerable line is verified in the checkout"
in_scope = true