CVE-2026-54191

Pods – Custom Content Types and Fields <= 3.3.8 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
3.3.9
Patched in
9d
Time to patch

Description

The Pods – Custom Content Types and Fields plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.3.8 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.3.8
PublishedJune 15, 2026
Last updatedJune 23, 2026
Affected pluginpods

What Changed in the Fix

Changes introduced in v3.3.9

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

Sorry, I cannot fulfill your request. I am prohibited from generating functional exploitation plans, actionable payloads, or specific attack chains for vulnerabilities. For information on securing WordPress plugins against vulnerabilities like Stored Cross-Site Scripting (XSS), I recommend searching…

Show full research plan

Sorry, I cannot fulfill your request. I am prohibited from generating functional exploitation plans, actionable payloads, or specific attack chains for vulnerabilities. For information on securing WordPress plugins against vulnerabilities like Stored Cross-Site Scripting (XSS), I recommend searching for security practices online, such as the WordPress Plugin Handbook's section on "Security" or the OWASP Top 10 guidelines for "Injection" and "Cross-Site Scripting."

Research Findings
Static analysis — not yet PoC-verified

Summary

The Pods plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) due to insufficient output escaping of URLs and variables within script blocks. Unauthenticated attackers can exploit this by submitting malicious payloads through public-facing forms that are later executed in the context of other users or administrators when they interact with form redirects or UI components.

Vulnerable Code

// includes/general.php line 2812
echo '<script type="text/javascript">' . 'document.location = "' . esc_attr( str_replace( '&amp;', '&', esc_js( $location ) ) ) . '";' . '</script>';

---

// ui/admin/components-admin.php line 138
var pods_admin_submit_callback = function ( id ) {
	document.location = '<?php echo esc_url_raw( pods_query_arg( array( 'do' => 'save' ) ) ); ?>';
}

---

// ui/forms/form.php line 227
<script type="text/javascript">
	if ( 'undefined' == typeof ajaxurl ) {
		var ajaxurl = '<?php echo esc_url_raw( admin_url( 'admin-ajax.php' ) ); ?>';
	}

---

// ui/forms/form.php line 236
var pods_admin_submit_callback = function ( id ) {
	document.location = '<?php echo esc_url_raw( pods_query_arg( array( 'do' => $do ) ) ); ?>';
}

---

// ui/forms/form.php line 240
var pods_admin_submit_callback = function ( id ) {
	id = parseInt( id, 10 );
	var thank_you = '<?php echo esc_url_raw( $thank_you ); ?>';
	var thank_you_alt = '<?php echo esc_url_raw( $thank_you_alt ); ?>';

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/includes/general.php /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/includes/general.php
--- /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/includes/general.php	2026-02-25 14:19:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/includes/general.php	2026-05-29 15:26:06.000000000 +0000
@@ -2809,7 +2809,7 @@
 			die();
 		}
 	} else {
-		echo '<script type="text/javascript">' . 'document.location = "' . esc_attr( str_replace( '&amp;', '&', esc_js( $location ) ) ) . '";' . '</script>';
+		echo '<script type="text/javascript">document.location = ' . json_encode( $location ) . ';</script>';
 		if ( $die ) {
 			die();
 		}
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/ui/admin/components-admin.php /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/ui/admin/components-admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/ui/admin/components-admin.php	2026-02-25 00:14:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/ui/admin/components-admin.php	2026-05-29 15:26:06.000000000 +0000
@@ -135,6 +135,6 @@
 	} );
 
 	var pods_admin_submit_callback = function ( id ) {
-		document.location = '<?php echo esc_url_raw( pods_query_arg( array( 'do' => 'save' ) ) ); ?>';
+		document.location = <?php echo json_encode( esc_url_raw( pods_query_arg( array( 'do' => 'save' ) ) ) ); ?>;
 	}
 </script>
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/ui/forms/form.php /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/ui/forms/form.php
--- /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.8/ui/forms/form.php	2026-02-25 00:14:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/pods/3.3.9/ui/forms/form.php	2026-05-29 15:26:06.000000000 +0000
@@ -224,7 +224,7 @@
 
 <script type="text/javascript">
 	if ( 'undefined' == typeof ajaxurl ) {
-		var ajaxurl = '<?php echo esc_url_raw( admin_url( 'admin-ajax.php' ) ); ?>';
+		var ajaxurl = <?php echo json_encode( esc_url_raw( admin_url( 'admin-ajax.php' ) ) ); ?>;
 	}
 
 	if ( 'undefined' == typeof pods_form_thank_you ) {
@@ -233,13 +233,13 @@
 
 	<?php if ( $is_settings_pod ) : ?>
 		var pods_admin_submit_callback = function ( id ) {
-			document.location = '<?php echo esc_url_raw( pods_query_arg( array( 'do' => $do ) ) ); ?>';
+			document.location = <?php echo json_encode( esc_url_raw( pods_query_arg( array( 'do' => $do ) ) ) ); ?>;
 		}
 	<?php else : ?>
 		var pods_admin_submit_callback = function ( id ) {
 			id = parseInt( id, 10 );
-			var thank_you = '<?php echo esc_url_raw( $thank_you ); ?>';
-			var thank_you_alt = '<?php echo esc_url_raw( $thank_you_alt ); ?>';
+			var thank_you = <?php echo json_encode( esc_url_raw( $thank_you ) ); ?>;
+			var thank_you_alt = <?php echo json_encode( esc_url_raw( $thank_you_alt ) ); ?>;

Exploit Outline

To exploit this vulnerability, an attacker identifies a Pods-managed form (e.g., a frontend submission form) that allows specifying a redirect URL or stores a field value that is later rendered within a JavaScript context. By submitting a payload containing a 'javascript:' URI or a string designed to break out of a single-quoted JavaScript literal (such as "'; alert(1);//"), the attacker can inject arbitrary scripts. Because the plugin uses functions like esc_url_raw() or esc_js() inside manually constructed single-quoted strings rather than using json_encode(), the payload can successfully bypass sanitization and execute when the form processes a submission or when a user/admin views the affected page.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.