Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : May 21, 2026

CVE-2026-7249: Location Weather <= 3.0.2 – Missing Authorization to Authenticated (Contributor+) Block Settings Modification and Cache Purging (location-weather)

CVE ID CVE-2026-7249
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 3.0.2
Patched Version 3.0.3
Disclosed May 20, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-7249:
A missing authorization vulnerability in the Location Weather plugin for WordPress (versions <= 3.0.2) allows authenticated attackers with Contributor-level access or higher to disable weather blocks and purge weather cache transients. The CVSS score is 4.3 (Medium) due to the requirement of authentication but low complexity and impact on availability.

Root Cause:
The vulnerable functions `splw_update_block_options()` and `lwp_clean_weather_transients()` in the file `location-weather/includes/Admin/AdminDashboard/Splw_Blocks_Page_Wrapper.php` lacked capability checks before processing AJAX requests. The diff shows the original code only verified a nonce but did not call `current_user_can()` or any equivalent authorization check. Additionally, the `splw_block_color_settings_ajax()` function in `location-weather/includes/Blocks/Blocks.php` and several other admin AJAX handlers had the same missing check. The nonces used in these AJAX actions were exposed to all authenticated users via `wp_localize_script()` on the `init` hook, meaning any logged-in user (down to Contributor) could obtain and reuse them.

Exploitation:
An authenticated attacker with Contributor-level access sends a POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to `splw_update_block_options` or `lwp_clean_weather_transients` (or other vulnerable actions), along with the exposed nonce and any required block/transient parameters. Since no authorization check exists, the request is processed even though Contributor users should not have permission to modify global block settings or purge all caches. The attacker can disable all weather blocks or flush the weather cache, causing disruption of the weather display functionality for all site visitors.

Patch Analysis:
The patch introduces a new helper function `location_weather_verify_capability()` in `location-weather/includes/functions.php` (lines 12-23). This function calls `current_user_can( location_weather_dashboard_capability() )`, which checks for `manage_options` capability (Administrator-level). If the check fails, it sends a 403 JSON error and halts execution. The patch adds a call to `location_weather_verify_capability()` at the beginning of each vulnerable AJAX handler: `splw_update_block_options()`, `lwp_clean_weather_transients()`, `splw_block_color_settings_ajax()`, and other admin functions. The old code in `splw_update_setting_options()` and `splw_get_user_consent()` directly called `current_user_can()` with the filter, which was moved into the centralized verification function.

Impact:
Successful exploitation allows an authenticated Contributor-level attacker to disable all weather blocks site-wide and purge all weather cache transients. This degrades the availability and functionality of the plugin, potentially breaking weather displays for all users. No data exposure or privilege escalation occurs, but the impact is complete denial of weather data presentation, which could be significant for sites relying on weather information.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/location-weather/includes/Admin/AdminDashboard/Splw_Blocks_Page_Wrapper.php
+++ b/location-weather/includes/Admin/AdminDashboard/Splw_Blocks_Page_Wrapper.php
@@ -253,6 +253,9 @@
 	 * Handle AJAX request to update block settings.
 	 */
 	public function splw_update_block_options() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
+
 		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splw_admin_settings_nonce' ) ) {
 			wp_send_json_error( __( 'Invalid nonce.', 'location-weather' ) );
@@ -274,10 +277,8 @@
 	 * Handle AJAX request to update block settings.
 	 */
 	public function splw_update_setting_options() {
-		// Check user capability.
-		if ( ! current_user_can( apply_filters( 'location_weather_access_capability', 'manage_options' ) ) ) {
-			wp_send_json_error( __( 'Unauthorized access.', 'location-weather' ), 403 );
-		}
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();

 		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splw_admin_settings_nonce' ) ) {
@@ -328,6 +329,9 @@
 	 * It performs nonce verification to ensure the request is legitimate.
 	 */
 	public function lwp_clean_weather_transients() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
+
 		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splw_admin_settings_nonce' ) ) {
 			wp_send_json_error( __( 'Invalid nonce.', 'location-weather' ) );
@@ -368,6 +372,8 @@
 	 * @return void
 	 */
 	public function splw_changelog_data() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splw_admin_settings_nonce' ) ) {
 			return;
@@ -655,10 +661,8 @@
 	 */
 	public function splw_get_user_consent() {

-		// Check user capability.
-		if ( ! current_user_can( apply_filters( 'location_weather_access_capability', 'manage_options' ) ) ) {
-			wp_send_json_error( __( 'Unauthorized access.', 'location-weather' ), 403 );
-		}
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();

 		// Verify nonce.
 		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
--- a/location-weather/includes/Admin/Admin_Notices.php
+++ b/location-weather/includes/Admin/Admin_Notices.php
@@ -122,6 +122,8 @@
 	 * @return void
 	 **/
 	public function dismiss_review_notice() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$post_data = wp_unslash( $_POST );

 		if ( ! isset( $post_data['nonce'] ) || ! wp_verify_nonce( sanitize_key( $post_data['nonce'] ), 'splw_review_notice' ) ) {
--- a/location-weather/includes/Admin/Preview/LW_Preview.php
+++ b/location-weather/includes/Admin/Preview/LW_Preview.php
@@ -47,6 +47,8 @@
 	 * @since 2.1.1
 	 */
 	public function backend_preview() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$nonce = isset( $_POST['ajax_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['ajax_nonce'] ) ) : '';

 		if ( ! wp_verify_nonce( $nonce, 'splwt_metabox_nonce' ) ) {
--- a/location-weather/includes/Admin/ShapedPlugin_Offer_Banner.php
+++ b/location-weather/includes/Admin/ShapedPlugin_Offer_Banner.php
@@ -150,6 +150,8 @@
 	 * @return void
 	 */
 	public function dismiss_offer_banner() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		check_ajax_referer( 'smart_tabs_offer_dismiss', 'nonce' );
 		$offer_id = isset( $_POST['offer_id'] ) ? sanitize_text_field( wp_unslash( $_POST['offer_id'] ) ) : '';

--- a/location-weather/includes/Admin/framework/functions/actions.php
+++ b/location-weather/includes/Admin/framework/functions/actions.php
@@ -18,6 +18,8 @@
 	 * @version 1.0.0
 	 */
 	function splwt_get_icons() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();

 		$nonce = ( ! empty( $_POST['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';

@@ -65,6 +67,8 @@
 	 * @version 1.0.0
 	 */
 	function splwt_export() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();

 		$nonce  = ( ! empty( $_GET['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
 		$unique = ( ! empty( $_GET['unique'] ) ) ? sanitize_text_field( wp_unslash( $_GET['unique'] ) ) : '';
@@ -100,7 +104,8 @@
 	 * @version 1.0.0
 	 */
 	function splwt_import_ajax() {
-
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$nonce  = ( ! empty( $_POST['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		$unique = ( ! empty( $_POST['unique'] ) ) ? sanitize_text_field( wp_unslash( $_POST['unique'] ) ) : '';
 		$data   = ( ! empty( $_POST['data'] ) ) ? wp_kses_post_deep( json_decode( wp_unslash( trim( $_POST['data'] ) ), true ) ) : array(); // phpcs:ignore
@@ -134,6 +139,8 @@
 	 * @version 1.0.0
 	 */
 	function splwt_reset_ajax() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();

 		$nonce  = ( ! empty( $_POST['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		$unique = ( ! empty( $_POST['unique'] ) ) ? sanitize_text_field( wp_unslash( $_POST['unique'] ) ) : '';
@@ -158,6 +165,8 @@
 	 * It performs nonce verification to ensure the request is legitimate.
 	 */
 	function lwp_clean_open_weather_transients() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$nonce = ( ! empty( $_POST['nonce'] ) ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splwt_options_nonce' ) ) {
 			wp_send_json_error(
--- a/location-weather/includes/Blocks/Blocks.php
+++ b/location-weather/includes/Blocks/Blocks.php
@@ -176,6 +176,8 @@
 	 * @return void
 	 */
 	public function splw_block_color_settings_ajax() {
+		// Check user capabilities, current_user_can() is called internally.
+		location_weather_verify_capability();
 		$nonce = isset( $_POST['splwBlockApiNonce'] ) ? sanitize_text_field( wp_unslash( $_POST['splwBlockApiNonce'] ) ) : '';

 		if ( ! wp_verify_nonce( $nonce, 'splw_block_api_nonce' ) ) {
--- a/location-weather/includes/functions.php
+++ b/location-weather/includes/functions.php
@@ -12,8 +12,18 @@
 /**
  * Plugin dashboard access capability.
  *
- * @return manage_options
+ * @return string
  */
 function location_weather_dashboard_capability() {
 	return apply_filters( 'location_weather_access_capability', 'manage_options' );
 }
+
+/**
+ * Verifies the current user has the required capability for admin AJAX actions.
+ * Sends a 403 JSON error and halts execution if the check fails.
+ */
+function location_weather_verify_capability() {
+	if ( ! current_user_can( location_weather_dashboard_capability() ) ) {
+		wp_send_json_error( __( 'Unauthorized access.', 'location-weather' ), 403 );
+	}
+}
--- a/location-weather/main.php
+++ b/location-weather/main.php
@@ -13,7 +13,7 @@
  * Plugin URI:        https://locationweather.io/?ref=1
  * Author:            ShapedPlugin LLC
  * Author URI:        https://shapedplugin.com/
- * Version:           3.0.2
+ * Version:           3.0.3
  * Requires at least: 5.0
  * Requires PHP:      7.4
  * License:           GPL v2 or later
@@ -31,7 +31,7 @@
 define( 'LOCATION_WEATHER_FILE', __FILE__ );
 define( 'LOCATION_WEATHER_URL', plugins_url( '', LOCATION_WEATHER_FILE ) );
 define( 'LOCATION_WEATHER_ASSETS', LOCATION_WEATHER_URL . '/assets' );
-define( 'LOCATION_WEATHER_VERSION', '3.0.2' );
+define( 'LOCATION_WEATHER_VERSION', '3.0.3' );

 require_once ABSPATH . 'wp-admin/includes/plugin.php';
 if ( ! ( is_plugin_active( 'location-weather-pro/main.php' ) || is_plugin_active_for_network( 'location-weather-pro/main.php' ) ) ) {
@@ -55,7 +55,7 @@
 	 *
 	 * @var string
 	 */
-	public $version = '3.0.2';
+	public $version = '3.0.3';

 	/**
 	 * The unique slug of this plugin.
@@ -203,6 +203,7 @@
 	 *  Location Weather ajax action.
 	 */
 	public function splw_ajax_location_weather() {
+
 		$nonce = isset( $_POST['splw_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['splw_nonce'] ) ) : '';
 		if ( ! wp_verify_nonce( $nonce, 'splw_nonce' ) ) {
 			wp_send_json_error( array( 'error' => esc_html__( 'Error: Invalid nonce verification.', 'location-weather' ) ), 401 );

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School