REPORT / 01
Analysis Report · Folder Analysis cache/user-submitted-posts_20260110 → cache/user-submitted-posts_20260113 — CVE-2026-0913
Shared security patch analysis results
02 ·
Lifecycle actions
cancel · resume · skip · regenerate
03 ·
Share this analysis
copy link · embed report
03 ·
CVE Security Analysis & Writeups
ai-generated · per cve
Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.
CVE-2026-0913
NVD
AI-Generated Analysis
05 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
library/shortcode-access.php
AI: 2 vulnerabilities
1 false positive, 1 true positive
CVE-2026-0913
--- cache/user-submitted-posts_20260110/library/shortcode-access.php 2026-01-17 00:17:38.175057947 +0000+++ cache/user-submitted-posts_20260113/library/shortcode-access.php 2026-01-17 00:21:23.340574026 +0000@@ -1,17 +1,17 @@ <?php // User Submitted Posts - Access Control /* - Shortcode: require login based on capability+ Shortcode: display content based on user capability Syntax: [usp_access cap="read" deny=""][/usp_access] Can use {tag} to output <tag>- See @ https://codex.wordpress.org/Roles_and_Capabilities#Capabilities+ https://wordpress.org/documentation/article/roles-and-capabilities/ */+ if (!function_exists('usp_access')) :+ function usp_access($attr, $content = null) {- extract(shortcode_atts(array(- 'cap' => 'read',- 'deny' => '',- ), $attr));+ + extract(shortcode_atts(array('cap' => 'read', 'deny' => ''), $attr)); // deny message @@ -20,7 +20,7 @@ $deny = str_replace("{", "<", $deny); $deny = str_replace("}", ">", $deny); - $deny = preg_replace('#<script(.*)>(.*)</script>#is', '', $deny);+ $deny = wp_kses_post($deny); // content @@ -29,71 +29,112 @@ $content = str_replace("{", "<", $content); $content = str_replace("}", ">", $content); - $content = preg_replace('#<script(.*)>(.*)</script>#is', '', $content);+ $content = wp_kses_post($content); // $caps = array_map('trim', explode(',', $cap)); foreach ($caps as $c) {+ if (current_user_can($c) && !is_null($content) && !is_feed()) return do_shortcode($content);+ } return $deny;+ }+ add_shortcode('usp_access', 'usp_access');+ endif; /* - Shortcode: show content to visitors+ Shortcode: display content to visitors (not logged in) Syntax: [usp_visitor deny=""][/usp_visitor] Can use {tag} to output <tag> */+ if (!function_exists('usp_visitor')) : + function usp_visitor($attr, $content = null) {- extract(shortcode_atts(array(- 'deny' => '',- ), $attr));+ + extract(shortcode_atts(array('deny' => ''), $attr));+ + // deny message+ + $deny = htmlspecialchars($deny, ENT_QUOTES); $deny = str_replace("{", "<", $deny); $deny = str_replace("}", ">", $deny); - $deny = htmlspecialchars($deny, ENT_QUOTES);+ $deny = wp_kses_post($deny);+ + // content+ $content = htmlspecialchars($content, ENT_QUOTES); + $content = str_replace("{", "<", $content);+ $content = str_replace("}", ">", $content);+ + $content = wp_kses_post($content);+ + //+ if ((!is_user_logged_in() && !is_null($content)) || is_feed()) return do_shortcode($content); return $deny;+ }+ add_shortcode('usp_visitor', 'usp_visitor');+ endif; /* - Shortcode: show content to members+ Shortcode: display content to members (logged in) Syntax: [usp_member deny=""][/usp_member] Can use {tag} to output <tag> */+ if (!function_exists('usp_member')) :+ function usp_member($attr, $content = null) {- extract(shortcode_atts(array(- 'deny' => '',- ), $attr));+ + extract(shortcode_atts(array('deny' => ''), $attr));+ + // deny message+ + $deny = htmlspecialchars($deny, ENT_QUOTES); $deny = str_replace("{", "<", $deny); $deny = str_replace("}", ">", $deny); - $deny = htmlspecialchars($deny, ENT_QUOTES);+ $deny = wp_kses_post($deny);+ + // content+ $content = htmlspecialchars($content, ENT_QUOTES); + $content = str_replace("{", "<", $content);+ $content = str_replace("}", ">", $content);+ + $content = wp_kses_post($content);+ + //+ if (is_user_logged_in() && !is_null($content) && !is_feed()) return do_shortcode($content); return $deny;+ }+ add_shortcode('usp_member', 'usp_member');+ endif; @@ -101,16 +142,26 @@ /* Shortcode Empty Paragraph Fix */+ if (!function_exists('usp_shortcode_empty_p_fix')) :+ function usp_shortcode_empty_p_fix($content) {+ $array = array(+ '<p>[' => '[', ']</p>' => ']', ']<br />' => ']', ']<br>' => ']'+ );+ $content = strtr($content, $array);+ return $content;+ }+ add_filter('the_content', 'usp_shortcode_empty_p_fix');-endif;++endif;\ No newline at end of file
AI Analysis
I'll analyze this code diff for security vulnerabilities.
Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - CWE-79 - library/shortcode-access.php Lines 23, 32
Old Code:
```php
$deny = preg_replace('#<script(.*)>(.*)</script>#is', '', $deny);
```
and
```php
$content = preg_replace('#<script(.*)>(.*)</script>#is', '', $content);
```
Fixed Code:
```php
$deny = wp_kses_post($deny);
```
and
```php
$content = wp_kses_post($content);
```
Explanation:
The original code attempted to sanitize user input by using a regex pattern to strip only `<script>` tags. This is insufficient because:
1. It only removes `<script>` tags but allows other dangerous HTML attributes and event handlers (e.g., `<img onerror="alert('xss')" />`, `<div onload="...">`)
2. The regex pattern can be bypassed with variations like `<SCRIPT>`, case variations, or nested tags
3. Other dangerous HTML/JavaScript vectors like style tags, iframe tags, and event handlers would pass through
The fix uses `wp_kses_post()`, which is WordPress's proper HTML sanitization function that:
1. Whitelists allowed HTML tags and attributes
2. Removes all potentially dangerous content
3. Is the standard WordPress approach for sanitizing post content
---
Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - CWE-79 - library/shortcode-access.php Lines 59, 75 (usp_visitor and usp_member functions)
Old Code:
```php
$deny = htmlspecialchars($deny, ENT_QUOTES);
$content = htmlspecialchars($content, ENT_QUOTES);
```
Fixed Code:
```php
$deny = htmlspecialchars($deny, ENT_QUOTES);
$deny = str_replace("{", "<", $deny);
$deny = str_replace("}", ">", $deny);
$deny = wp_kses_post($deny);
$content = htmlspecialchars($content, ENT_QUOTES);
$content = str_replace("{", "<", $content);
$content = str_replace("}", ">", $content);
$content = wp_kses_post($content);
```
Explanation:
The original code used only `htmlspecialchars()` for sanitization, which escapes HTML entities but doesn't remove dangerous tags. After the `{` and `}` replacement (converting them to `<` and `>`), the code would have unescaped HTML tags that could contain XSS payloads. The fix properly applies `wp_kses_post()` after the character replacements to ensure all HTML content is properly sanitized and only safe tags/attributes are allowed.
CVE Analysis Results:
CVE-2026-0913: Yes
View CVE Description
The User Submitted Posts – Enable Users to Submit Posts from the Front End plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'usp_access' shortcode in all versions up to, and including, 20260110 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
Showing 1 to 1 of 1 results