Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/jetformbuilder/includes/blocks/render/media-field-render.php
+++ b/jetformbuilder/includes/blocks/render/media-field-render.php
@@ -75,7 +75,7 @@
// preset field
$updated = str_replace( '<!-- field -->', $this->get_field_preset( $file ), $updated );
- $image_ext = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'svg', 'webp' );
+ $image_ext = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'svg', 'webp', 'avif' );
$img_ext_preg = '!.(' . join( '|', $image_ext ) . ')$!i';
if ( preg_match( $img_ext_preg, $file['url'] ) ) {
--- a/jetformbuilder/includes/classes/resources/file-tools.php
+++ b/jetformbuilder/includes/classes/resources/file-tools.php
@@ -30,7 +30,13 @@
}
protected static function is_same_file( File $file, Uploaded_File $uploaded_file ): bool {
- $info = pathinfo( $uploaded_file->get_url() );
+ $preset_path = $uploaded_file->get_attachment_file();
+
+ if ( ! $preset_path ) {
+ return false;
+ }
+
+ $info = pathinfo( $preset_path );
return $file->get_name() === ( $info['basename'] ?? '' );
}
--- a/jetformbuilder/includes/classes/resources/uploaded-file.php
+++ b/jetformbuilder/includes/classes/resources/uploaded-file.php
@@ -96,17 +96,17 @@
public function set_from_array( array $upload ): Uploaded_File {
if ( isset( $upload['file'] ) ) {
- $this->file = $upload['file'];
+ $this->file = self::normalize_allowed_upload_file_path( (string) $upload['file'] );
}
if ( isset( $upload['url'] ) ) {
- $this->url = $upload['url'];
+ $this->url = esc_url_raw( (string) $upload['url'] );
}
if ( isset( $upload['type'] ) ) {
- $this->type = $upload['type'];
+ $this->type = sanitize_mime_type( (string) $upload['type'] );
}
if ( isset( $upload['id'] ) ) {
- $this->set_attachment_id( (string) $upload['id'] );
+ $this->set_attachment_id( (string) absint( $upload['id'] ) );
}
return $this;
@@ -185,7 +185,10 @@
$file = $this->get_file();
if ( $file ) {
- return $file;
+ $file = self::normalize_allowed_upload_file_path( $file );
+ if ( $file ) {
+ return $file;
+ }
}
$id = $this->get_attachment_id();
@@ -197,13 +200,59 @@
$file = get_attached_file( $id );
- return is_string( $file ) ? $file : '';
+ if ( ! is_string( $file ) ) {
+ return '';
+ }
+
+ return self::normalize_allowed_upload_file_path( $file );
}
/**
* @param string $url
*/
public function set_url( string $url ) {
- $this->url = $url;
+ $this->url = esc_url_raw( $url );
+ }
+
+ /**
+ * Normalize path and allow only existing files inside wp-content uploads directory.
+ *
+ * @return string Normalized realpath to a file in uploads, or empty string.
+ */
+ public static function normalize_allowed_upload_file_path( string $file ): string {
+ if ( '' === $file ) {
+ return '';
+ }
+
+ $path = wp_normalize_path( $file );
+ $real = realpath( $path );
+
+ if ( false === $real ) {
+ return '';
+ }
+
+ $real = wp_normalize_path( $real );
+ $real = untrailingslashit( $real );
+
+ $uploads = wp_get_upload_dir();
+ $base = (string) ( $uploads['basedir'] ?? '' );
+
+ if ( '' === $base ) {
+ return '';
+ }
+
+ $base_real = realpath( $base );
+ if ( false === $base_real ) {
+ return '';
+ }
+
+ $base = wp_normalize_path( $base_real );
+ $base = untrailingslashit( $base );
+
+ if ( 0 === strpos( $real, $base . '/' ) && is_file( $real ) ) {
+ return $real;
+ }
+
+ return '';
}
}
--- a/jetformbuilder/jet-form-builder.php
+++ b/jetformbuilder/jet-form-builder.php
@@ -3,7 +3,7 @@
* Plugin Name: JetFormBuilder
* Plugin URI: https://jetformbuilder.com/
* Description: Advanced form builder plugin for WordPress block editor. Create forms from the ground up, customize the existing ones, and style them up – all in one editor.
- * Version: 3.5.6.2
+ * Version: 3.5.6.3
* Author: Crocoblock
* Author URI: https://crocoblock.com/
* Text Domain: jet-form-builder
@@ -18,7 +18,7 @@
die();
}
-const JET_FORM_BUILDER_VERSION = '3.5.6.2';
+const JET_FORM_BUILDER_VERSION = '3.5.6.3';
const JET_FORM_BUILDER__FILE__ = __FILE__;
const JET_FORM_BUILDER_SITE = 'https://jetformbuilder.com';
--- a/jetformbuilder/modules/actions-v2/send-email/send-email-action.php
+++ b/jetformbuilder/modules/actions-v2/send-email/send-email-action.php
@@ -5,6 +5,7 @@
use Jet_Form_BuilderActionsAction_Handler;
use Jet_Form_BuilderActionsTypesBase;
use Jet_Form_BuilderClassesHttpHttp_Tools;
+use Jet_Form_BuilderClassesResourcesUploaded_File;
use Jet_Form_BuilderClassesTools;
use Jet_Form_BuilderExceptionsAction_Exception;
use Jet_Form_BuilderRequestRequest_Tools;
@@ -397,7 +398,29 @@
);
}
- return $attachments;
+ return $this->filter_safe_attachments( $attachments );
+ }
+
+ /**
+ * Allow only readable files within the uploads directory.
+ */
+ private function filter_safe_attachments( array $attachments ): array {
+ $safe = array();
+
+ foreach ( $attachments as $attachment ) {
+ if ( ! is_string( $attachment ) || '' === $attachment ) {
+ continue;
+ }
+
+ $allowed = Uploaded_File::normalize_allowed_upload_file_path( $attachment );
+ if ( '' === $allowed || ! is_file( $allowed ) || ! is_readable( $allowed ) ) {
+ continue;
+ }
+
+ $safe[] = $allowed;
+ }
+
+ return array_values( array_unique( $safe ) );
}
public function update_headers() {
--- a/jetformbuilder/modules/form-record/admin/meta-boxes/form-record-values-box.php
+++ b/jetformbuilder/modules/form-record/admin/meta-boxes/form-record-values-box.php
@@ -37,15 +37,19 @@
}
public function get_columns(): array {
- return array(
- 'form' => new Form_Link_Column(),
- 'referrer' => new Referrer_Link_Column(),
- 'status' => new Status_Column(),
- 'user' => new User_Login_Column(),
- 'ip_address' => new Ip_Address_Column(),
- 'user_agent' => new User_Agent_Column(),
- 'created_at' => new Created_At_Column(),
- 'updated_at' => new Updated_At_Column(),
+ return apply_filters(
+ 'jet-form-builder/form-record/general-values-columns',
+ array(
+ 'form' => new Form_Link_Column(),
+ 'referrer' => new Referrer_Link_Column(),
+ 'status' => new Status_Column(),
+ 'user' => new User_Login_Column(),
+ 'ip_address' => new Ip_Address_Column(),
+ 'user_agent' => new User_Agent_Column(),
+ 'created_at' => new Created_At_Column(),
+ 'updated_at' => new Updated_At_Column(),
+ ),
+ $this
);
}
--- a/jetformbuilder/vendor/composer/installed.php
+++ b/jetformbuilder/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'crocoblock/jetformbuilder',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => 'df7eef93139074f35204bd3ed0fc03d3d263e22a',
+ 'reference' => '21e39eda416b2024c54d26fb7dc33550a16f8069',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'crocoblock/jetformbuilder' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => 'df7eef93139074f35204bd3ed0fc03d3d263e22a',
+ 'reference' => '21e39eda416b2024c54d26fb7dc33550a16f8069',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),