Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion easy-image-gallery.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Plugin Name: Easy Image Gallery
Plugin URI: https://devrix.com/
Description: An easy to use image gallery with drag & drop re-ordering
Version: 1.5.4
Version: 1.5.5
Author: DevriX
Author URI: https://devrix.com/
Text Domain: easy-image-gallery
Expand Down
38 changes: 34 additions & 4 deletions includes/metabox.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function easy_image_gallery_metabox() {
$get_galleries = array(
array(
array(
'SHORTCODE' => wp_rand( 100, 999 ),
'SHORTCODE' => (string) wp_rand( 100000, 999999999 ),
'DATA' => $get_gallery_old_data,
'OPEN_IMAGES' => $get_open_images[0],
),
Expand All @@ -110,8 +110,21 @@ function easy_image_gallery_metabox() {

$gallery_count = -1;
if ( isset( $get_galleries ) && ! empty( $get_galleries ) ) {
$existing_shortcodes = array();

foreach ( $get_galleries[0] as $gallery ) {
$gallery_count = $gallery_count + 1;

$gallery_shortcode = easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] );
if ( '' === $gallery_shortcode || in_array( $gallery_shortcode, $existing_shortcodes, true ) ) {
do {
$candidate = (string) wp_rand( 100000, 999999999 );
} while ( in_array( $candidate, $existing_shortcodes, true ) );

$gallery_shortcode = $candidate;
}
Comment thread
metodiew marked this conversation as resolved.

$existing_shortcodes[] = $gallery_shortcode;
$get_attachments = $gallery['DATA'];

// Convert attachements to string
Expand Down Expand Up @@ -139,8 +152,8 @@ function easy_image_gallery_metabox() {
<a href="#" class="dx-eig-gallery-add-images button" data-count="<?php echo esc_attr( (string) $gallery_count ); ?>"><?php esc_html_e( 'Add images to the gallery', 'easy-image-gallery' ); ?></a>
<span class="eig-remove"><img src="<?php echo esc_url( EASY_IMAGE_GALLERY_URL . 'includes/fonts/close.png' ); ?>" alt=""></span>
<a href="#" class="button button-primary button-small dx-eig-insert-shortcode">Insert this shortcode in the content</a>
<input type="text" class="dx-eig-shortcode" name="image_gallery[<?php echo esc_attr( (string) $gallery_count ); ?>][SHORTCODE]" value="<?php echo esc_attr( (string) $gallery['SHORTCODE'] ); ?>" hidden>
<input type="text" class="dx-eig-shortcode-show" readonly="" value="<?php echo esc_attr( '[easy_image_gallery gallery="' . $gallery['SHORTCODE'] . '"]' ); ?>">
<input type="text" class="dx-eig-shortcode" name="image_gallery[<?php echo esc_attr( (string) $gallery_count ); ?>][SHORTCODE]" value="<?php echo esc_attr( $gallery_shortcode ); ?>" hidden>
<input type="text" class="dx-eig-shortcode-show" readonly="" value="<?php echo esc_attr( '[easy_image_gallery gallery="' . $gallery_shortcode . '"]' ); ?>">
<div class="link-image-to-l">
<label for="easy_image_gallery_link_images_<?php echo esc_attr( (string) $gallery_count ); ?>">
<input type="checkbox" id="easy_image_gallery_link_images_<?php echo esc_attr( (string) $gallery_count ); ?>" value="on" name="image_gallery[<?php echo esc_attr( (string) $gallery_count ); ?>][OPEN_IMAGES]" <?php checked( isset( $gallery['OPEN_IMAGES'] ) ? $gallery['OPEN_IMAGES'] : '', 'on' ); ?> /> <?php esc_html_e( 'Link images to larger sizes', 'easy-image-gallery' ); ?>
Expand Down Expand Up @@ -398,6 +411,8 @@ function easy_image_gallery_save_post( $post_id ) {

$easy_image_gallery_post = map_deep( wp_unslash( $_POST['image_gallery'] ), 'sanitize_text_field' );

$existing_shortcodes = array();

foreach ( $easy_image_gallery_post as $gallery ) {
if ( ! is_array( $gallery ) ) {
continue;
Expand All @@ -412,7 +427,22 @@ function easy_image_gallery_save_post( $post_id ) {
}

$gallery['DATA'] = $convert_to_arr;
$galleries[] = $gallery;

if ( isset( $gallery['SHORTCODE'] ) ) {
$gallery['SHORTCODE'] = easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] );

if ( '' === $gallery['SHORTCODE'] || in_array( $gallery['SHORTCODE'], $existing_shortcodes, true ) ) {
do {
$candidate = (string) wp_rand( 100000, 999999999 );
} while ( in_array( $candidate, $existing_shortcodes, true ) );

$gallery['SHORTCODE'] = $candidate;
}

$existing_shortcodes[] = $gallery['SHORTCODE'];
}

$galleries[] = $gallery;
}

update_post_meta( $post_id, '_easy_image_gallery_v2', $galleries );
Expand Down
97 changes: 72 additions & 25 deletions includes/template-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function easy_image_gallery_get_image_ids( $post_id = null, $all_galleries_image

if( isset( $new_db_structure ) && !empty( $new_db_structure ) ){
foreach( $new_db_structure as $gallery ){
if( $gallery['SHORTCODE'] == $gallery_id ){
if ( (string) easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] ) === (string) easy_image_gallery_sanitize_gallery_id( $gallery_id ) ) {
return $gallery['DATA'];
}
}
Expand Down Expand Up @@ -216,43 +216,65 @@ function easy_image_gallery_get_lightbox() {
endif;


/**
* Sanitize a gallery/shortcode ID for safe use in HTML attributes and selectors.
*
* Gallery IDs are numeric (see wp_rand-generated SHORTCODE values in the metabox).
*
* @since 1.5.5
* @param mixed $gallery_id Gallery identifier.
* @return string Digits-only ID, or empty string when invalid.
*/
function easy_image_gallery_sanitize_gallery_id( $gallery_id ) {
if ( null === $gallery_id || '' === $gallery_id || 'old_db' === $gallery_id ) {
return '';
}

$sanitized_gallery_id = preg_replace( '/[^0-9]/', '', (string) $gallery_id );

if ( '' === $sanitized_gallery_id ) {
return '';
}

return $sanitized_gallery_id;
}

/**
* Returns the correct rel attribute for the anchor links
*
* @since 1.0
* @return string
*/

function easy_image_gallery_lightbox_rel( $gallery_id = null ) {

$lightbox = easy_image_gallery_get_lightbox();
$gallery_id = easy_image_gallery_sanitize_gallery_id( $gallery_id );
$lightbox = easy_image_gallery_get_lightbox();

switch ( $lightbox ) {

case 'prettyphoto':

$rel = 'rel="prettyPhoto' . '[group-'.$gallery_id.']"';
$rel = 'rel="' . esc_attr( 'prettyPhoto[group-' . $gallery_id . ']' ) . '"';

break;

case 'fancybox':

$rel = 'data-fancybox="gallery'.$gallery_id.'"';
$rel = 'data-fancybox="' . esc_attr( 'gallery' . $gallery_id ) . '"';

break;

case 'luminous':

$rel = 'rel="luminous' . '[group-'.$gallery_id.']"';
$rel = 'rel="' . esc_attr( 'luminous[group-' . $gallery_id . ']' ) . '"';

break;

default:

$rel = 'rel="prettyPhoto' . '[group-'.$gallery_id.']"';
$rel = 'rel="' . esc_attr( 'prettyPhoto[group-' . $gallery_id . ']' ) . '"';
}


return $rel;
}

Expand Down Expand Up @@ -362,15 +384,27 @@ function easy_image_gallery_get_galleries() {
function easy_image_gallery_shortcode( $atts ) {

// return early if the post type is not allowed to have a gallery
if ( !easy_image_gallery_allowed_post_type() ){
return;
}else{
if ( isset($atts['gallery']) && !empty($atts['gallery']) ){
return easy_image_gallery( $atts['gallery'] );
}else{
return easy_image_gallery( 'old_db' );
}
}
if ( ! easy_image_gallery_allowed_post_type() ) {
return '';
}
Comment thread
metodiew marked this conversation as resolved.

$atts = shortcode_atts(
array(
'gallery' => '',
),
$atts,
'easy_image_gallery'
);

if ( ! empty( $atts['gallery'] ) ) {
$gallery_id = easy_image_gallery_sanitize_gallery_id( $atts['gallery'] );
if ( '' !== $gallery_id ) {
return easy_image_gallery( $gallery_id );
}
return '';
}

return easy_image_gallery( 'old_db' );
}
add_shortcode( 'easy_image_gallery', 'easy_image_gallery_shortcode' );

Expand All @@ -387,7 +421,7 @@ function easy_image_gallery_count_images( $gallery_shortcode ) {

if ( isset($galleries) && !empty($galleries) ) {
foreach ( $galleries as $gallery ){
if ( $gallery['SHORTCODE'] == $gallery_shortcode ){
if ( (string) easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] ) === (string) easy_image_gallery_sanitize_gallery_id( $gallery_shortcode ) ) {
$number = count($gallery['DATA']);
return $number;
}
Expand All @@ -412,11 +446,24 @@ function easy_image_gallery( $gallery_id = 'old_db' ) {
ob_start();
foreach ($galleries as $gallery){

if ($gallery_id == 'old_db'){
$gallery_id = $gallery['SHORTCODE'];
}
$current_gallery_id = $gallery_id;

if ( 'old_db' === $current_gallery_id ) {
$candidate = easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] );
if ( '' === $candidate ) {
// Couldn't derive a valid numeric ID from this gallery; try the next one.
continue;
}

$current_gallery_id = $candidate;
} else {
$current_gallery_id = easy_image_gallery_sanitize_gallery_id( $current_gallery_id );
if ( '' === $current_gallery_id ) {
continue;
}
}

if ( $gallery['SHORTCODE'] == $gallery_id ){
if ( (string) easy_image_gallery_sanitize_gallery_id( $gallery['SHORTCODE'] ) === (string) $current_gallery_id ) {
$gallery_exist = true;

$has_gallery_images = $gallery['DATA'];
Expand Down Expand Up @@ -458,10 +505,10 @@ function easy_image_gallery( $gallery_id = 'old_db' ) {

$lightbox = easy_image_gallery_get_lightbox();

$rel = easy_image_gallery_lightbox_rel( $gallery_id );
$rel = easy_image_gallery_lightbox_rel( $current_gallery_id );

if ( isset($gallery['OPEN_IMAGES']) && $gallery['OPEN_IMAGES'] == 'on' )
$html = sprintf( '<li><a %s href="%s" class="%s" title="%s" data-caption="%s" target="_blank"><i class="icon-view"></i><span class="overlay"></span>%s</a></li>', $rel, $image_link, $image_class, $image_caption, $image_caption, $image );
$html = sprintf( '<li><a %s href="%s" class="%s" title="%s" data-caption="%s" target="_blank"><i class="icon-view"></i><span class="overlay"></span>%s</a></li>', $rel, esc_url( $image_link ), $image_class, $image_caption, $image_caption, $image );
else
$html = sprintf( '<li>%s</li>', $image );

Expand All @@ -470,7 +517,7 @@ function easy_image_gallery( $gallery_id = 'old_db' ) {
echo '</ul>';

if ( easy_image_gallery_get_lightbox() === 'luminous' ) {
$luminous_selector = sprintf( "a[rel='luminous[group-%s]']", $gallery_id );
$luminous_selector = sprintf( "a[rel='luminous[group-%s]']", easy_image_gallery_sanitize_gallery_id( $current_gallery_id ) );
printf(
'<script>new LuminousGallery(document.querySelectorAll(%s));</script>',
wp_json_encode( $luminous_selector )
Expand Down
6 changes: 5 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contributors: devrix, nofearinc
Tags: image gallery, image, galleries, simple, easy, devrix
Requires at least: 3.5
Tested up to: 6.9.4
Stable tag: 1.5.4
Stable tag: 1.5.5
Comment thread
metodiew marked this conversation as resolved.
Requires PHP: 7.4.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -118,6 +118,10 @@ The plugin ownership was transferred to DevriX. There are no functionality chang

== Changelog ==

= 1.5.5 =
* Security: Escape gallery IDs in lightbox HTML attributes (fancybox, prettyPhoto, luminous) to prevent stored XSS via shortcode or post meta.
* Security: Sanitize gallery IDs on save and in the [easy_image_gallery] shortcode.

= 1.5.4 =
* Fixed vulnerability report
* Tested up to WordPress 6.9.4
Expand Down