Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/autoptimize/autoptimize.php
+++ b/autoptimize/autoptimize.php
@@ -3,7 +3,7 @@
* Plugin Name: Autoptimize
* Plugin URI: https://autoptimize.com/pro/
* Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
- * Version: 3.1.14
+ * Version: 3.1.15
* Author: Frank Goossens (futtta)
* Author URI: https://autoptimize.com/pro/
* Text Domain: autoptimize
@@ -21,7 +21,7 @@
exit;
}
-define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.1.14' );
+define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.1.15' );
// plugin_dir_path() returns the trailing slash!
define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
--- a/autoptimize/classes/autoptimizeExtra.php
+++ b/autoptimize/classes/autoptimizeExtra.php
@@ -467,7 +467,7 @@
$preload_as = 'other';
}
- $preload_output .= '<link rel="preload" href="' . $preload . '" as="' . $preload_as . '"' . $mime_type . $crossorigin . '>';
+ $preload_output .= '<link rel="preload" fetchpriority="high" href="' . $preload . '" as="' . $preload_as . '"' . $mime_type . $crossorigin . '>';
}
$preload_output = apply_filters( 'autoptimize_filter_extra_preload_output', $preload_output );
--- a/autoptimize/classes/autoptimizeImages.php
+++ b/autoptimize/classes/autoptimizeImages.php
@@ -801,7 +801,7 @@
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && empty( $to_preload ) && false !== apply_filters( 'autoptimize_filter_imgopt_dopreloads', true ) ) {
// the preload was not in an img tag, so adding a non-responsive preload instead.
foreach ( $metabox_preloads as $img_preload ) {
- $to_preload .= '<link rel="preload" href="' . $img_preload . '" as="image">';
+ $to_preload .= apply_filters( 'autoptimize_filter_imgopt_preload_tag_result', $this->kses_preload_link( '<link fetchpriority="high" rel="preload" href="' . $img_preload . '" as="image">' ) );
}
}
@@ -935,7 +935,7 @@
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && empty( $to_preload ) && false !== apply_filters( 'autoptimize_filter_imgopt_dopreloads', true ) ) {
// the preload was not in an img tag, so adding a non-responsive preload instead.
foreach ( $metabox_preloads as $img_preload ) {
- $to_preload .= '<link rel="preload" href="' . $img_preload . '" as="image">';
+ $to_preload .= apply_filters( 'autoptimize_filter_imgopt_preload_tag_result', $this->kses_preload_link( '<link fetchpriority="high" rel="preload" href="' . $img_preload . '" as="image">' ) );
}
}
@@ -984,8 +984,9 @@
$placeholder = apply_filters( 'autoptimize_filter_imgopt_lazyload_placeholder', $this->get_default_lazyload_placeholder( $width, $height ) );
}
- $tag = preg_replace( '/(s)src=/', ' src='' . $placeholder . '' data-src=', $tag );
- $tag = preg_replace( '/(s)srcset=/', ' data-srcset=', $tag );
+ $tag = str_replace( ' src=', ' data-src=', $tag );
+ $tag = str_replace( ' srcset=', ' data-srcset=', $tag );
+ $tag = str_replace( '<img ', '<img src='' . $placeholder . '' ', $tag );
// move sizes to data-sizes unless filter says no.
if ( apply_filters( 'autoptimize_filter_imgopt_lazyload_move_sizes', true ) ) {
@@ -1053,11 +1054,21 @@
// rewrite img tag to link preload img.
$_from = array( '<img ', ' src=', ' sizes=', ' srcset=' );
- $_to = array( '<link rel="preload" as="image" ', ' href=', ' imagesizes=', ' imagesrcset=' );
+ $_to = array( '<link fetchpriority="high" rel="preload" as="image" ', ' href=', ' imagesizes=', ' imagesrcset=' );
$tag = str_replace( $_from, $_to, $tag );
- // and using kses, remove all unneeded attributes
- // keeping only those we *know* are OK and/ or needed
+ // sanitize output
+ $tag = $this->kses_preload_link( $tag );
+
+ // and provide filter for late changes.
+ $tag = apply_filters( 'autoptimize_filter_imgopt_preload_tag_result', $tag );
+
+ return $tag;
+ }
+
+ public static function kses_preload_link( $_preload ) {
+ // using kses, remove all unneeded attributes
+ // keeping only those we *know* are OK and/ or needed.
$allowed_html = array(
'link' => array(
'rel' => true,
@@ -1067,11 +1078,12 @@
'imagesrcset' => true,
'type' => true,
'media' => true,
+ 'fetchpriority' => true,
),
);
- $tag = wp_kses( $tag, $allowed_html );
+ $_preload = wp_kses( $_preload, $allowed_html );
- return $tag;
+ return $_preload;
}
public static function get_cdn_url() {
--- a/autoptimize/classes/autoptimizeMetabox.php
+++ b/autoptimize/classes/autoptimizeMetabox.php
@@ -273,7 +273,7 @@
foreach ( apply_filters( 'autoptimize_filter_meta_valid_optims', array( 'ao_post_optimize', 'ao_post_js_optimize', 'ao_post_css_optimize', 'ao_post_ccss', 'ao_post_lazyload', 'ao_post_preload' ) ) as $opti_type ) {
if ( in_array( $opti_type, apply_filters( 'autoptimize_filter_meta_optim_nonbool', array( 'ao_post_preload' ) ) ) ) {
if ( isset( $_POST[ $opti_type ] ) ) {
- $ao_meta_result[ $opti_type ] = $_POST[ $opti_type ];
+ $ao_meta_result[ $opti_type ] = sanitize_text_field( $_POST[ $opti_type ] );
} else {
$ao_meta_result[ $opti_type ] = false;
}
--- a/autoptimize/classes/external/php/ao-minify-html.php
+++ b/autoptimize/classes/external/php/ao-minify-html.php
@@ -98,7 +98,7 @@
$this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
}
- $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
+ $this->_replacementHash = 'MINIFYHTML' . bin2hex( random_bytes( 16 ) );
$this->_placeholders = array();
// replace SCRIPTs (and minify) with placeholders