--- a/foogallery/extensions/albums/admin/class-metaboxes.php
+++ b/foogallery/extensions/albums/admin/class-metaboxes.php
@@ -408,12 +408,46 @@
}
}
+ /**
+ * Validate incoming AJAX context for album gallery details requests.
+ *
+ * Reviewers : please note that we cannot check if the gallery belongs to the album, as the user might be in the process of creating an album
+ *
+ * @return array|false
+ */
+ private function validate_gallery_details_ajax_context() {
+ $album_id = isset( $_POST['foogallery_album_id'] ) ? absint( wp_unslash( $_POST['foogallery_album_id'] ) ) : 0;
+ $foogallery_id = isset( $_POST['foogallery_id'] ) ? absint( wp_unslash( $_POST['foogallery_id'] ) ) : 0;
+
+ if ( $album_id <= 0 || $foogallery_id <= 0 ) {
+ return false;
+ }
+
+ if ( ! current_user_can( 'edit_post', $album_id ) || ! current_user_can( 'edit_post', $foogallery_id ) ) {
+ return false;
+ }
+
+ $album = FooGalleryAlbum::get_by_id( $album_id );
+ $gallery = FooGallery::get_by_id( $foogallery_id );
+
+ if ( false === $album || false === $gallery ) {
+ return false;
+ }
+
+ return array(
+ 'album_id' => $album_id,
+ 'foogallery_id' => $foogallery_id,
+ 'gallery' => $gallery,
+ );
+ }
+
public function ajax_get_gallery_details() {
if ( check_admin_referer( 'foogallery_album_gallery_details' ) ) {
- $foogallery_id = intval( $_POST['foogallery_id'] );
- $gallery = FooGallery::get_by_id( $foogallery_id );
+ $context = $this->validate_gallery_details_ajax_context();
- if ( false !== $gallery ) {
+ if ( false !== $context ) {
+ $foogallery_id = $context['foogallery_id'];
+ $gallery = $context['gallery'];
$fields = $this->get_gallery_detail_fields( $gallery ); ?>
<form name="foogallery_gallery_details">
<input type="hidden" name="foogallery_id" id="foogallery_id" value="<?php echo esc_attr( $foogallery_id ); ?>" />
@@ -511,22 +545,39 @@
public function ajax_save_gallery_details() {
if ( check_admin_referer( 'foogallery_album_gallery_details' ) ) {
- $foogallery_id = $_POST['foogallery_id'];
- $gallery = FooGallery::get_by_id( $foogallery_id );
- if ( false !== $gallery ) {
- $fields = $this->get_gallery_detail_fields( $gallery );
-
- foreach ( $fields as $field => $values ) {
- //for every field, save some info
- do_action( 'foogallery_album_gallery_details_save', $field, $values, $gallery );
- }
+ $context = $this->validate_gallery_details_ajax_context();
+ if ( false === $context ) {
+ wp_send_json_error( array(
+ 'message' => __( 'Invalid gallery details request.', 'foogallery' ),
+ ), 403 );
}
+
+ $gallery = $context['gallery'];
+ $fields = $this->get_gallery_detail_fields( $gallery );
+
+ foreach ( $fields as $field => $values ) {
+ //for every field, save some info
+ do_action( 'foogallery_album_gallery_details_save', $field, $values, $gallery );
+ }
+
+ wp_send_json_success();
}
}
public function gallery_details_save($field, $field_args, $gallery) {
+ if ( ! isset( $_POST[$field] ) ) {
+ return;
+ }
+
if ( 'custom_url' === $field || 'custom_target' === $field ) {
- $value = $_POST[$field];
+ $value = wp_unslash( $_POST[$field] );
+
+ if ( 'custom_url' === $field ) {
+ $value = esc_url_raw( $value );
+ } else {
+ $value = sanitize_key( $value );
+ }
+
update_post_meta( $gallery->ID, $field, $value );
}
}
--- a/foogallery/extensions/import-export/class-foogallery-import-export.php
+++ b/foogallery/extensions/import-export/class-foogallery-import-export.php
@@ -466,6 +466,12 @@
*/
public function ajax_generate_export() {
if ( check_admin_referer( 'foogallery_gallery_export' ) ) {
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error( array(
+ 'message' => __( 'You do not have permission to export galleries.', 'foogallery' ),
+ ), 403 );
+ }
+
if ( isset( $_POST['galleries'] ) ) {
$galleries = array_map( 'sanitize_text_field', wp_unslash( $_POST['galleries'] ) );
echo foogallery_generate_export_json( $galleries ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON output
--- a/foogallery/foogallery.php
+++ b/foogallery/foogallery.php
@@ -3,7 +3,7 @@
/*
Plugin Name: FooGallery
Description: FooGallery is the most intuitive and extensible gallery management tool ever created for WordPress
-Version: 3.1.11
+Version: 3.1.13
Author: FooPlugins
Plugin URI: https://fooplugins.com/foogallery-wordpress-gallery-plugin/
Author URI: https://fooplugins.com
@@ -24,7 +24,7 @@
define( 'FOOGALLERY_PATH', plugin_dir_path( __FILE__ ) );
define( 'FOOGALLERY_URL', plugin_dir_url( __FILE__ ) );
define( 'FOOGALLERY_FILE', __FILE__ );
- define( 'FOOGALLERY_VERSION', '3.1.11' );
+ define( 'FOOGALLERY_VERSION', '3.1.13' );
define( 'FOOGALLERY_SETTINGS_VERSION', '2' );
require_once FOOGALLERY_PATH . 'includes/constants.php';
require_once FOOGALLERY_PATH . 'includes/functions.php';
--- a/foogallery/gutenberg/class-foogallery-blocks.php
+++ b/foogallery/gutenberg/class-foogallery-blocks.php
@@ -48,10 +48,16 @@
$path = FOOGALLERY_PATH . 'gutenberg/assets/blocks';
$url = FOOGALLERY_URL . 'gutenberg/assets/blocks';
- $asset = require_once( $path . '.asset.php' );
+ $asset = require( $path . '.asset.php' );
+ if ( ! is_array( $asset ) ) {
+ $asset = array(
+ 'dependencies' => array(),
+ 'version' => false,
+ );
+ }
- if ( is_array( $asset[ 'dependencies' ] ) ){
- $asset[ 'dependencies' ][] = 'foogallery-core';
+ if ( isset( $asset['dependencies'] ) && is_array( $asset['dependencies'] ) ){
+ $asset['dependencies'][] = 'foogallery-core';
}
// Scripts.
--- a/foogallery/includes/admin/class-attachment-fields.php
+++ b/foogallery/includes/admin/class-attachment-fields.php
@@ -190,7 +190,15 @@
// If our fields array is not empty
if ( ! empty( $custom_fields ) ) {
- // We browse our set of options
+
+ $post_id = absint( $post['ID'] );
+
+ // get out early if we don't have a post id or we don't have permission to edit it.
+ if ( $post_id === 0 || !current_user_can( 'edit_post', $post_id ) ) {
+ return $post;
+ }
+
+ // We browse our set of options
foreach ( $custom_fields as $field => $values ) {
switch ( $values['input'] ) {
case 'text':
@@ -200,18 +208,28 @@
case 'checkbox':
// If this field has been submitted (is present in the $attachment variable)
if ( isset( $attachment[$field] ) ) {
+ $value = wp_unslash( $attachment[ $field ] );
+
+ if ( 'foogallery_custom_url' === $field ) {
+ $value = foogallery_sanitize_attachment_custom_url( $value );
+ } elseif ( 'foogallery_custom_target' === $field ) {
+ $value = foogallery_sanitize_attachment_custom_target( $value );
+ } else {
+ $value = sanitize_text_field( $value );
+ }
+
// If submitted field is empty
// We add errors to the post object with the "error_text" parameter if set in the options
- if ( strlen( trim( $attachment[$field] ) ) == 0 && isset( $values['error_text'] ) ) {
+ if ( strlen( trim( $value ) ) == 0 && isset( $values['error_text'] ) ) {
$post['errors'][ $field ]['errors'][] = __( $values['error_text'] );
// Otherwise we update the custom field
} else {
- update_post_meta( $post['ID'], '_' . $field, $attachment[ $field ] );
+ update_post_meta( $post_id, '_' . $field, $value );
}
}
// Otherwise, we delete it if it already existed
else {
- delete_post_meta( $post['ID'], $field );
+ delete_post_meta( $post_id, '_' . $field );
}
break;
@@ -224,4 +242,4 @@
return $post;
}
}
-}
No newline at end of file
+}
--- a/foogallery/includes/admin/class-gallery-attachment-modal.php
+++ b/foogallery/includes/admin/class-gallery-attachment-modal.php
@@ -331,11 +331,13 @@
}
if ( array_key_exists( 'custom-url', $data ) ) {
- update_post_meta( $img_id, '_foogallery_custom_url', $data['custom-url'] );
+ $custom_url = foogallery_sanitize_attachment_custom_url( wp_unslash( $data['custom-url'] ) );
+ update_post_meta( $img_id, '_foogallery_custom_url', $custom_url );
}
if ( array_key_exists( 'custom-target', $data ) ) {
- update_post_meta( $img_id, '_foogallery_custom_target', $data['custom-target'] );
+ $custom_target = foogallery_sanitize_attachment_custom_target( wp_unslash( $data['custom-target'] ) );
+ update_post_meta( $img_id, '_foogallery_custom_target', $custom_target );
}
if ( array_key_exists( 'custom-class', $data ) ) {
--- a/foogallery/includes/admin/class-menu.php
+++ b/foogallery/includes/admin/class-menu.php
@@ -118,6 +118,12 @@
function create_demo_galleries() {
if ( check_ajax_referer( 'foogallery_admin_import_demos' ) ) {
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error( array(
+ 'message' => __( 'You do not have permission!', 'foogallery' ),
+ ), 403 );
+ }
+
$results = foogallery_create_demo_content();
if ( $results === false ) {
--- a/foogallery/includes/class-foogallery-attachment-custom-class.php
+++ b/foogallery/includes/class-foogallery-attachment-custom-class.php
@@ -69,7 +69,7 @@
public function load_custom_class_meta( $foogallery_attachment, $post ) {
$custom_class = get_post_meta( $post->ID, '_foogallery_custom_class', true );
if ( !empty( $custom_class ) ) {
- $foogallery_attachment->custom_class = $custom_class;
+ $foogallery_attachment->custom_class = foogallery_sanitize_javascript( $custom_class );
}
}
}
--- a/foogallery/includes/class-foogallery-attachment.php
+++ b/foogallery/includes/class-foogallery-attachment.php
@@ -49,8 +49,8 @@
$this->caption = trim( $post->post_excerpt );
$this->description = trim( $post->post_content );
$this->alt = trim( get_post_meta( $this->ID, '_wp_attachment_image_alt', true ) );
- $this->custom_url = get_post_meta( $this->ID, '_foogallery_custom_url', true );
- $this->custom_target = get_post_meta( $this->ID, '_foogallery_custom_target', true );
+ $this->custom_url = foogallery_sanitize_attachment_custom_url( get_post_meta( $this->ID, '_foogallery_custom_url', true ) );
+ $this->custom_target = foogallery_sanitize_attachment_custom_target( get_post_meta( $this->ID, '_foogallery_custom_target', true ) );
$this->load_attachment_image_data( $this->ID );
$this->date = !empty( $post->post_date_gmt ) ? $post->post_date_gmt : $post->post_date;
--- a/foogallery/includes/class-foogallery-cache.php
+++ b/foogallery/includes/class-foogallery-cache.php
@@ -210,6 +210,12 @@
function ajax_clear_all_caches() {
if ( check_admin_referer( 'foogallery_clear_html_cache' ) ) {
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error( array(
+ 'message' => __( 'You do not have permission!', 'foogallery' ),
+ ), 403 );
+ }
+
$this->clear_all_gallery_caches();
esc_html_e('The cache for all galleries has been cleared!', 'foogallery' );
--- a/foogallery/includes/class-override-thumbnail.php
+++ b/foogallery/includes/class-override-thumbnail.php
@@ -81,6 +81,12 @@
);
}
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error( array(
+ 'message' => __( 'You do not have permission!', 'foogallery' ),
+ ), 403 );
+ }
+
$img_id = isset( $_POST['img_id'] ) ? absint( wp_unslash( $_POST['img_id'] ) ) : 0;
if ( ! $img_id ) {
--- a/foogallery/includes/functions.php
+++ b/foogallery/includes/functions.php
@@ -1506,6 +1506,48 @@
}
/**
+ * Sanitize attachment custom URLs before persisting or rendering.
+ *
+ * @since 1.0.0
+ *
+ * @param string $url
+ * @return string
+ */
+function foogallery_sanitize_attachment_custom_url( $url ) {
+ if ( !is_string( $url ) ) {
+ return '';
+ }
+ $url = trim( $url );
+ if ( '' === $url ) {
+ return '';
+ }
+ return esc_url_raw( $url );
+}
+
+/**
+ * Sanitize attachment custom target values against known options.
+ *
+ * @since 1.0.0
+ *
+ * @param string $target
+ * @return string
+ */
+function foogallery_sanitize_attachment_custom_target( $target ) {
+ if ( !is_string( $target ) ) {
+ return '';
+ }
+ $target = sanitize_key( $target );
+ if ( '' === $target ) {
+ return '';
+ }
+ $target_options = foogallery_get_target_options();
+ if ( array_key_exists( $target, $target_options ) ) {
+ return $target;
+ }
+ return 'default';
+}
+
+/**
* Sanitize HTML to make it safe to output. Used to sanitize potentially harmful HTML used for captions
*
* @since 1.9.23
@@ -1939,10 +1981,10 @@
$attachment_args['meta_input']['_wp_attachment_image_alt'] = $attachment_data['alt'];
}
if ( isset( $attachment_data['custom_url'] ) && !empty( $attachment_data['custom_url'] ) ) {
- $attachment_args['meta_input']['_foogallery_custom_url'] = $attachment_data['custom_url'];
+ $attachment_args['meta_input']['_foogallery_custom_url'] = foogallery_sanitize_attachment_custom_url( $attachment_data['custom_url'] );
}
if ( isset( $attachment_data['custom_target'] ) && !empty( $attachment_data['custom_target'] ) ) {
- $attachment_args['meta_input']['_foogallery_custom_target'] = $attachment_data['custom_target'];
+ $attachment_args['meta_input']['_foogallery_custom_target'] = foogallery_sanitize_attachment_custom_target( $attachment_data['custom_target'] );
}
if ( isset( $attachment_data['video'] ) && !empty( $attachment_data['video'] ) ) {
$attachment_args['meta_input']['_foogallery_video_data'] = array(
--- a/foogallery/includes/render-functions.php
+++ b/foogallery/includes/render-functions.php
@@ -130,7 +130,7 @@
// get the URL to the attachment page.
$url = get_attachment_link( $foogallery_attachment->ID );
} elseif ( 'custom' === $link ) {
- $url = $args['custom_link'];
+ $url = foogallery_sanitize_attachment_custom_url( $args['custom_link'] );
} else {
$url = $foogallery_attachment->url;
}
@@ -606,4 +606,4 @@
}
$html .= '>';
return $html;
-}
No newline at end of file
+}