Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-3813: utils.php in jupiterx-core/trunk/includes/extensions/raven/includes – WordPress Plugin Repository

The Jupiter X Core plugin for WordPress is vulnerable to arbitrary file downloads in versions up to, and including, 2.5.0. This makes it possible for unauthenticated attackers to download the contents of arbitrary files on the server, which can contain sensitive information. The requires the premium version of the plugin to be activated.

CVE
#wordpress#php#auth

1<?php2/**3 * Adds utils.4 *5 * @package JupiterX_Core\Raven6 * @since 1.0.07 */89namespace JupiterX_Core\Raven;1011defined( ‘ABSPATH’ ) || die();1213use Elementor\Controls_Stack;14use Elementor\Plugin as Elementor;1516/**17 * Raven utils class.18 *19 * Raven utils handler class is responsible for different utility methods20 * used by Raven.21 *22 * @since 1.0.023 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)24 */25class Utils {2627 /**28 * A list of safe tage for `validate_html_tag` method.29 */30 const ALLOWED_HTML_WRAPPER_TAGS = [31 'a’,32 'article’,33 'aside’,34 'button’,35 'div’,36 'footer’,37 'h1’,38 'h2’,39 'h3’,40 'h4’,41 'h5’,42 'h6’,43 'header’,44 'main’,45 'nav’,46 'p’,47 'section’,48 'span’,49 ];5051 /**52 * Get the svg directory path.53 *54 * @since 1.0.055 * @access public56 * @static57 *58 * @param string $file_name SVG file name.59 * @return string Directory path.60 */61 public static function get_svg( $file_name = ‘’ ) {62 if ( empty( $file_name ) ) {63 return $file_name;64 }6566 return Plugin::$plugin_path . ‘assets/img/’ . $file_name . '.svg’;67 }6869 /**70 * Generate data-parallax based on params.71 *72 * @since 1.0.073 * @access public74 * @static75 *76 * @param int $pxs_x X position.77 * @param int $pxs_y Y position.78 * @param int $pxs_z Z position.79 * @param int $pxs_smoothness Smoothness level.80 *81 * @return string Data attribute.82 */83 public static function parallax_scroll( $pxs_x, $pxs_y, $pxs_z, $pxs_smoothness ) {84 $parallax_scroll = [];8586 if ( ! empty( $pxs_x ) ) {87 $parallax_scroll[] = ‘"x":’ . $pxs_x;88 }8990 if ( ! empty( $pxs_y ) ) {91 $parallax_scroll[] = ‘"y":’ . $pxs_y;92 }9394 if ( ! empty( $pxs_z ) ) {95 $parallax_scroll[] = ‘"z":’ . $pxs_z;96 }9798 if ( ! empty( $pxs_smoothness ) ) {99 $parallax_scroll[] = ‘"smoothness":’ . $pxs_smoothness;100 }101102 if ( empty( $parallax_scroll ) ) {103 return;104 }105106 return ‘{’ . implode( ',’, $parallax_scroll ) . '}’;107 }108109 /**110 * Get site domain.111 *112 * @since 1.0.0113 * @access public114 * @static115 *116 * @return string Site domain.117 */118 public static function get_site_domain() {119 // @codingStandardsIgnoreStart120 // Get the site domain and get rid of www.121 $sitename = strtolower( sanitize_text_field( $_SERVER[‘SERVER_NAME’] ) );122123 if ( substr( $sitename, 0, 4 ) == ‘www.’ ) {124 $sitename = substr( $sitename, 4 );125 }126127 return $sitename;128 // @codingStandardsIgnoreEnd129 }130131 /**132 * Get WP_Query arguments.133 *134 * Retrieving arguments from element settings.135 *136 * @since 1.0.0137 * @access public138 * @static139 *140 * @param array $settings Widget settings.141 *142 * @return args Prepared WP_Query arguments.143 *144 * @SuppressWarnings(PHPMD.CyclomaticComplexity)145 * @SuppressWarnings(PHPMD.NPathComplexity)146 */147 public static function get_query_args( $settings ) {148 $settings = array_merge(149 [150 ‘query_post_type’ => 'post’,151 ‘query_posts_per_page’ => 3,152 ‘query_orderby’ => 'date’,153 ‘query_order’ => 'DESC’,154 ‘category’ => -1,155 ],156 $settings157 );158159 $args = [160 ‘post_type’ => $settings[‘query_post_type’],161 ‘posts_per_page’ => $settings[‘query_posts_per_page’],162 ‘orderby’ => $settings[‘query_orderby’],163 ‘order’ => $settings[‘query_order’],164 ‘post_status’ => 'publish’,165 ‘ignore_sticky_posts’ => empty( $settings[‘query_ignore_sticky_posts’] ) ? 0 : 1,166 ‘paged’ => max( 1, get_query_var( ‘paged’ ), get_query_var( ‘page’ ) ),167 ];168169 // Only use offset on all category state.170 if ( -1 === $settings[‘category’] && ! empty( $settings[‘query_offset’] ) ) {171 $args[‘offset_proper’] = $settings[‘query_offset’];172 }173174 if ( ! empty( $settings[‘paged’] ) ) {175 $args[‘paged’] = $settings[‘paged’];176 }177178 if ( ! empty( $settings[‘query_excludes’] ) ) {179 $current_post_key = array_search( 'current_post’, $settings[‘query_excludes’], true );180181 // If current_post is existing in the array values replace it with the current post viewing ID.182 if ( false !== $current_post_key ) {183 $settings[‘query_excludes’][ $current_post_key ] = get_the_ID();184 }185186 $args[‘post__not_in’] = $settings[‘query_excludes’];187188 if ( ! empty( $settings[‘query_excludes_ids’] ) && is_array( $settings[‘query_excludes_ids’] ) ) {189 $args[‘post__not_in’] = array_merge( $args[‘post__not_in’], $settings[‘query_excludes_ids’] );190 }191 }192193 if ( ! empty( $settings[ ‘query_’ . $args[‘post_type’] . ‘_includes’ ] ) ) {194 $args[‘post__in’] = $settings[ ‘query_’ . $args[‘post_type’] . ‘_includes’ ];195 }196197 if ( ! empty( $settings[‘query_authors’] ) ) {198 $args[‘author__in’] = $settings[‘query_authors’];199 }200201 $taxonomies = get_object_taxonomies( $args[‘post_type’], ‘names’ );202203 if ( ! empty( $settings[‘category’] ) && $settings[‘category’] > 0 && ! empty( $taxonomies ) ) {204 $args[‘tax_query’] = [];205206 $taxonomies_length = count( $taxonomies );207208 for ( $i = 0; $i < $taxonomies_length; $i++ ) {209 if ( false === strpos( $taxonomies[ $i ], ‘cat’ ) ) {210 continue;211 }212213 $args[‘tax_query’][] = [214 ‘taxonomy’ => $taxonomies[ $i ],215 ‘field’ => 'term_id’,216 ‘terms’ => $settings[‘category’],217 ];218219 break;220 }221 } elseif ( empty( $settings[ ‘query_’ . $args[‘post_type’] . ‘_includes’ ] ) && ! empty( $taxonomies ) ) {222 $args[‘tax_query’] = [];223224 foreach ( $taxonomies as $taxonomy ) {225 $taxonomy_control_id = ‘query_’ . $taxonomy . '_ids’;226227 if ( ! empty( $settings[ $taxonomy_control_id ] ) ) {228 $args[‘tax_query’][] = [229 ‘taxonomy’ => $taxonomy,230 ‘field’ => 'term_id’,231 ‘terms’ => $settings[ $taxonomy_control_id ],232 ];233 }234 }235 }236237 return $args;238 }239240 /**241 * Get responsive class base on settings key.242 *243 * @since 1.0.0244 * @access public245 * @static246 *247 * @param string $prefix Before class string.248 * @param string $key Settings key.249 * @param string $settings Settings stored.250 *251 * @return string|void Responsive class.252 */253 public static function get_responsive_class( $prefix = '’, $key = '’, $settings = ‘’ ) {254 if ( empty( $prefix ) || empty( $key ) || empty( $settings ) ) {255 return;256 }257258 $devices = [259 Controls_Stack::RESPONSIVE_DESKTOP,260 Controls_Stack::RESPONSIVE_TABLET,261 Controls_Stack::RESPONSIVE_MOBILE,262 ];263264 if ( Elementor::$instance->experiments->is_feature_active( ‘additional_custom_breakpoints’ ) ) {265 $devices = [ ‘desktop’ ];266267 foreach ( Elementor::$instance->breakpoints->get_active_breakpoints() as $breakpoint ) {268 $devices[] = $breakpoint->get_name();269 }270 }271272 $classes = [];273274 foreach ( $devices as $device_name ) {275 $temp_key = \Elementor\Controls_Stack::RESPONSIVE_DESKTOP === $device_name ? $key : $key . ‘_’ . $device_name;276277 if ( ! isset( $settings[ $temp_key ] ) ) {278 return;279 }280281 $device = \Elementor\Controls_Stack::RESPONSIVE_DESKTOP === $device_name ? ‘’ : '-' . $device_name;282283 $classes[] = sprintf( $prefix . $settings[ $temp_key ], $device );284 }285286 return implode( ' ', $classes );287 }288289290 /**291 * Get element settings recursively.292 *293 * Retrieve specific element settings by model ID.294 *295 * @param array $elements Page elements.296 * @param string $model_id Element model id.297 *298 * @return array|false Return array if element found.299 */300 public static function find_element_recursive( $elements, $model_id ) {301 foreach ( $elements as $element ) {302 if ( $model_id === $element[‘id’] ) {303 return $element;304 }305306 if ( ! empty( $element[‘elements’] ) ) {307 $element = self::find_element_recursive( $element[‘elements’], $model_id );308309 if ( $element ) {310 return $element;311 }312 }313 }314315 return false;316 }317318 /**319 * Wrapper around the core WP get_plugins function, making sure it’s actually available.320 *321 * @since 1.0.0322 * @access public323 * @static324 *325 * @param string $plugin_folder Optional. Relative path to single plugin folder.326 *327 * @return array Array of installed plugins with plugin information.328 */329 public static function get_plugins( $plugin_folder = ‘’ ) {330 if ( ! function_exists( ‘get_plugins’ ) ) {331 require_once ABSPATH . 'wp-admin/includes/plugin.php’;332 }333334 return get_plugins( $plugin_folder );335 }336337 /**338 * Checks if a plugin is installed. Does not take must-use plugins into account.339 *340 * @since 1.0.0341 * @access public342 * @static343 *344 * @param string $slug Required. Plugin slug.345 *346 * @return bool True if installed, false otherwise.347 */348 public static function is_plugin_installed( $slug ) {349 return ! empty( self::get_plugins( ‘/’ . $slug ) );350 }351352 /**353 * Get automatic direction based on RTL/LTR.354 *355 * @since 1.0.0356 *357 * @param string $direction The direction.358 *359 * @return string The direction.360 */361 public static function get_direction( $direction ) {362 if ( ! is_rtl() ) {363 return $direction;364 }365366 if ( false !== stripos( $direction, ‘left’ ) ) {367 return str_replace( 'left’, 'right’, $direction );368 }369370 if ( false !== stripos( $direction, ‘right’ ) ) {371 return str_replace( 'right’, 'left’, $direction );372 }373374 return $direction;375 }376377 /**378 * Get post ID based on document.379 *380 * @since 1.0.0381 */382 public static function get_current_post_id() {383 if ( isset( Elementor::$instance->documents ) && ! empty( Elementor::$instance->documents->get_current() ) ) {384 return Elementor::$instance->documents->get_current()->get_main_id();385 }386387 return get_the_ID();388 }389390 /**391 * Get Client IP Address.392 *393 * @since 1.2.0394 * @access private395 * @static396 *397 * @return string398 */399 public static function get_client_ip() {400 // phpcs:disable WordPress.Security.ValidatedSanitizedInput401 if ( isset( $_SERVER[‘HTTP_CLIENT_IP’] ) ) {402 $ip_address = sanitize_text_field( $_SERVER[‘HTTP_CLIENT_IP’] );403 } elseif ( isset( $_SERVER[‘HTTP_X_FORWARDED_FOR’] ) ) {404 $ip_address = sanitize_text_field( $_SERVER[‘HTTP_X_FORWARDED_FOR’] );405 } elseif ( isset( $_SERVER[‘HTTP_X_FORWARDED’] ) ) {406 $ip_address = sanitize_text_field( $_SERVER[‘HTTP_X_FORWARDED’] );407 } elseif ( isset( $_SERVER[‘HTTP_FORWARDED_FOR’] ) ) {408 $ip_address = sanitize_text_field( $_SERVER[‘HTTP_FORWARDED_FOR’] );409 } elseif ( isset( $_SERVER[‘HTTP_FORWARDED’] ) ) {410 $ip_address = sanitize_text_field( $_SERVER[‘HTTP_FORWARDED’] );411 } elseif ( isset( $_SERVER[‘REMOTE_ADDR’] ) ) {412 $ip_address = sanitize_text_field( $_SERVER[‘REMOTE_ADDR’] );413 }414 // phpcs:enable415 return $ip_address;416 }417418 /**419 * Download File.420 *421 * @since 1.2.0422 * @access public423 * @static424 */425 public static function handle_file_download() {426 $file = filter_input( INPUT_GET, ‘file’ );427 $nonce = filter_input( INPUT_GET, ‘_wpnonce’ );428429 // Validate nonce.430 if ( empty( $nonce ) || ! wp_verify_nonce( $nonce ) ) {431 wp_die( ‘<script>window.close();</script>’ );432 }433434 $file = base64_decode( $file ); // phpcs:ignore435 $upload_dir = wp_get_upload_dir();436437 // Make sure file exists.438 if ( empty( $file ) || ! file_exists( $file ) ) {439 wp_die( ‘<script>window.close();</script>’ );440 }441442 // Restrict the download to WP upload directory.443 if ( strpos( $file, $upload_dir[‘basedir’] ) > 0 ) {444 wp_die( ‘<script>window.close();</script>’ );445 }446447 $file_name = pathinfo( $file, PATHINFO_BASENAME );448 $file_ext = pathinfo( $file, PATHINFO_EXTENSION );449450 // Strip hash.451 $file_name = str_replace( $file_ext, '’, $file_name );452 $file_parts = explode( '__’, $file_name );453 $file_name = array_shift( $file_parts );454 $file_name .= ‘.’ . $file_ext;455456 header( ‘Content-Description: File Transfer’ );457 header( ‘Content-Type: application/octet-stream’ );458 header( ‘Content-Disposition: attachment; filename="’ . $file_name . ‘"’ );459 header( ‘Expires: 0’ );460 header( ‘Cache-Control: must-revalidate’ );461 header( ‘Pragma: public’ );462 header( 'Content-Length: ' . filesize( $file ) );463 // phpcs:ignore WordPress.WP.AlternativeFunctions464 readfile( $file );465 }466467 /**468 * Refresh Global product variable.469 *470 * @since 2.5.0471 * @access public472 * @static473 */474 public static function get_product() {475 global $product;476477 if ( ! empty( wc_get_product() ) ) {478 $product = wc_get_product();479480 return $product;481 }482483 $args = [484 ‘post_type’ => 'product’,485 ‘stock’ => 1,486 ‘posts_per_page’ => 1,487 ‘orderby’ => 'date’,488 ‘order’ => 'DESC’,489 ];490491 $last_product = get_posts( $args );492493 if ( empty( $last_product ) ) {494 return;495 }496497 $last = $last_product[0];498 $product = wc_get_product( $last->ID );499500 return wc_get_product( $last->ID );501 }502503 /**504 * Get page title based on a current query.505 *506 * @param bool $include_context whether to prefix result with the context.507 * @return string the page title.508 * @since 2.5.0509 * @access public510 * @static511 *512 * @SuppressWarnings(PHPMD.CyclomaticComplexity)513 * @SuppressWarnings(PHPMD.NPathComplexity)514 */515 public static function get_page_title( $include_context = true ) {516 $title = '’;517518 if ( is_singular() ) {519 $singular_name = get_post_type_object( get_post_type() )->labels->singular_name;520 $title = $include_context ? $singular_name . ': ' . get_the_title() : get_the_title();521522 return $title;523 }524525 if ( is_search() ) {526 $title = esc_html__( 'Search Results for: ', ‘jupiterx-core’ ) . get_search_query();527 $title .= get_query_var( ‘paged’ ) ? esc_html__( ' – Page ', ‘jupiterx-core’ ) . get_query_var( ‘paged’ ) : '’;528529 return $title;530 }531532 if ( is_category() ) {533 $title = $include_context ? esc_html__( 'Category: ', ‘jupiterx-core’ ) : '’;534 $title .= single_cat_title( '’, false );535536 return $title;537 }538539 if ( is_tag() ) {540 $title = $include_context ? esc_html__( 'Tag: ', ‘jupiterx-core’ ) : '’;541 $title .= single_tag_title( '’, false );542543 return $title;544 }545546 if ( is_author() ) {547 $title = $include_context ? esc_html__( 'Author: ', ‘jupiterx-core’ ) : '’;548 $title .= ‘<span class="vcard">’ . get_the_author() . '</span>’;549550 return $title;551 }552553 if ( is_year() ) {554 $title = $include_context ? esc_html__( 'Year: ', ‘jupiterx-core’ ) : '’;555 $title .= get_the_date( _x( 'Y’, 'yearly archives date format’, ‘jupiterx-core’ ) );556557 return $title;558 }559560 if ( is_month() ) {561 $title = $include_context ? esc_html__( 'Month: ', ‘jupiterx-core’ ) : '’;562 $title .= get_the_date( _x( 'F Y’, 'monthly archives date format’, ‘jupiterx-core’ ) );563564 return $title;565 }566567 if ( is_day() ) {568 $title = $include_context ? esc_html__( 'Day: ', ‘jupiterx-core’ ) : '’;569 $title .= get_the_date( _x( 'F j, Y’, 'daily archives date format’, ‘jupiterx-core’ ) );570571 return $title;572 }573574 if ( is_tax( ‘post_format’ ) ) {575 if ( is_tax( 'post_format’, ‘post-format-aside’ ) ) {576 return _x( 'Asides’, 'post format archive title’, ‘jupiterx-core’ );577 }578579 if ( is_tax( 'post_format’, ‘post-format-gallery’ ) ) {580 return _x( 'Galleries’, 'post format archive title’, ‘jupiterx-core’ );581 }582583 if ( is_tax( 'post_format’, ‘post-format-image’ ) ) {584 return _x( 'Images’, 'post format archive title’, ‘jupiterx-core’ );585 }586587 if ( is_tax( 'post_format’, ‘post-format-video’ ) ) {588 return _x( 'Videos’, 'post format archive title’, ‘jupiterx-core’ );589 }590591 if ( is_tax( 'post_format’, ‘post-format-quote’ ) ) {592 return _x( 'Quotes’, 'post format archive title’, ‘jupiterx-core’ );593 }594595 if ( is_tax( 'post_format’, ‘post-format-link’ ) ) {596 return _x( 'Links’, 'post format archive title’, ‘jupiterx-core’ );597 }598599 if ( is_tax( 'post_format’, ‘post-format-status’ ) ) {600 return _x( 'Statuses’, 'post format archive title’, ‘jupiterx-core’ );601 }602603 if ( is_tax( 'post_format’, ‘post-format-audio’ ) ) {604 return _x( 'Audio’, 'post format archive title’, ‘jupiterx-core’ );605 }606607 if ( is_tax( 'post_format’, ‘post-format-chat’ ) ) {608 return _x( 'Chats’, 'post format archive title’, ‘jupiterx-core’ );609 }610 }611612 if ( is_post_type_archive() ) {613 $title = $include_context ? esc_html__( 'Archives: ', ‘jupiterx-core’ ) : '’;614 $title .= post_type_archive_title( '’, false );615616 return $title;617 }618619 if ( is_tax() ) {620 $tax_singular_name = get_taxonomy( get_queried_object()->taxonomy )->labels->singular_name;621622 $title = $include_context ? $tax_singular_name . ': ' : '’;623 $title .= single_term_title( '’, false );624625 return $title;626 }627628 if ( is_archive() ) {629 return esc_html__( 'Archives’, ‘jupiterx-core’ );630 }631632 if ( is_404() ) {633 return esc_html__( 'Page Not Found’, ‘jupiterx-core’ );634 }635636 return $title;637 }638}

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907