REPORT / 01

Analysis Report · Folder Analysis cache/newsletter_9.1.0 → cache/newsletter_9.1.1 — CVE-2026-1051

Shared security patch analysis results

mode patchdiff ai claude_cli haiku
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-1051 NVD
AI-Generated Analysis
05 · Findings filter · search · paginate
Use quotes for exact: "SQL injection" · Operators: hello AND bye, admin OR root, -error, NOT warning
Showing 0 to 0 of 0 results
unsubscription/unsubscription.php AI: Not Sure 4 true positives CVE-2026-1051
--- cache/newsletter_9.1.0/unsubscription/unsubscription.php	2026-01-20 00:24:22.900048631 +0000+++ cache/newsletter_9.1.1/unsubscription/unsubscription.php	2026-01-20 00:26:01.382141429 +0000@@ -19,7 +19,7 @@     function __construct() {         parent::__construct('unsubscription'); -        add_filter('newsletter_replace', [$this, 'hook_newsletter_replace'], 10, 4);+        add_filter('newsletter_replace', [$this, 'hook_newsletter_replace'], 10, 5);         add_filter('newsletter_page_text', [$this, 'hook_newsletter_page_text'], 10, 3);         add_filter('newsletter_message', [$this, 'hook_newsletter_message'], 9, 3); @@ -48,6 +48,7 @@         $label = empty($attrs['label']) ? __('Unsubscribe', 'newsletter') : $attrs['label'];          $b = '<form action="' . esc_attr($this->build_action_url('uc')) . '" method="post" class="tnp-button-form tnp-unsubscribe">';+        $b .= wp_nonce_field('newsletter-unsubscribe', '_wpnonce', true, false);         $b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';         $b .= '<button class="tnp-submit">' . esc_html($label) . '</button>';         $b .= '</form>';@@ -63,6 +64,7 @@          $label = empty($attrs['label']) ? __('Resubscribe', 'newsletter') : $attrs['label'];         $b = '<form action="' . esc_attr($this->build_action_url('reactivate')) . '" method="post" class="tnp-button-form tnp-reactivate">';+        $b .= wp_nonce_field('newsletter-reactivate', '_wpnonce', true, false);         $b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';         $b .= '<button class="tnp-submit">' . esc_html($label) . '</button>';         $b .= '</form>';@@ -137,7 +139,10 @@                 break;              case 'uc':-+                $verified = wp_verify_nonce($_REQUEST['_wpnonce'], 'newsletter-unsubscribe');+                if (!$verified) {+                    $this->redirect($this->build_action_url('u', $user, $email));+                }                 $this->unsubscribe($user, $email);                 $url = $this->build_message_url(null, 'unsubscribed', $user, $email);                 setcookie('newsletter', '', 0, '/');@@ -153,6 +158,10 @@                 break;              case 'reactivate':+                $verified = wp_verify_nonce($_REQUEST['_wpnonce'], 'newsletter-unsubscribe');+                if (!$verified) {+                    die('Unverified request');+                }                 $this->reactivate($user);                 setcookie('newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/');                 $url = $this->build_message_url(null, 'reactivated', $user);@@ -228,14 +237,28 @@         do_action('newsletter_user_reactivated', $user);     } -    function hook_newsletter_replace($text, $user, $email, $html = true) {+    function get_unsubscribe_url($user, $email = null) {+        return $this->build_action_url('u', $user, $email);+    }++    function hook_newsletter_replace($text, $user, $email, $html = true, $context = null) {          if ($user) {-            $text = $this->replace_url($text, 'unsubscription_confirm_url', $this->build_action_url('uc', $user, $email));+            $url = $this->build_action_url('uc', $user, $email);+            if ('page' === $context) {+                $url = wp_nonce_url($url, 'newsletter-unsubscribe');+            }+            $text = $this->replace_url($text, 'unsubscription_confirm_url', $url);             $text = $this->replace_url($text, 'unsubscription_url', $this->build_action_url('u', $user, $email));             $text = $this->replace_url($text, 'unsubscribe_url', $this->build_action_url('u', $user, $email));-            $text = $this->replace_url($text, 'reactivate_url', $this->build_action_url('reactivate', $user, $email));-            $text = $this->replace_url($text, 'reactivation_url', $this->build_action_url('reactivate', $user, $email));++            $url = $this->build_action_url('reactivate', $user, $email);+            if ('page' === $context) {+                $url = wp_nonce_url($url, 'newsletter-reactivate');+            }++            $text = $this->replace_url($text, 'reactivate_url', $url);+            $text = $this->replace_url($text, 'reactivation_url', $url);         } else {             $text = $this->replace_url($text, 'unsubscription_confirm_url', $this->build_action_url('nul'));             $text = $this->replace_url($text, 'unsubscription_url', $this->build_action_url('nul'));
AI Analysis
# Security Analysis - PatchLeaks Code Diff

Based on the provided code diff for `unsubscription/unsubscription.php`, here is my security analysis:

---

## Vulnerability 1

**Vulnerability Existed:** yes
TRUE POSITIVE

**Cross-Site Request Forgery (CSRF) - CWE-352 - unsubscription.php lines 50, 66**

**Old Code:**
```php
$b = '<form action="' . esc_attr($this->build_action_url('uc')) . '" method="post" class="tnp-button-form tnp-unsubscribe">';
$b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';
```

**Fixed Code:**
```php
$b = '<form action="' . esc_attr($this->build_action_url('uc')) . '" method="post" class="tnp-button-form tnp-unsubscribe">';
$b .= wp_nonce_field('newsletter-unsubscribe', '_wpnonce', true, false);
$b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';
```

**Explanation:**
The form was previously missing CSRF protection. The fix adds WordPress nonce field (`wp_nonce_field`) to protect against CSRF attacks. This generates a unique token that is validated server-side before processing the unsubscription request.

---

## Vulnerability 2

**Vulnerability Existed:** yes
TRUE POSITIVE

**Cross-Site Request Forgery (CSRF) - CWE-352 - unsubscription.php lines 66**

**Old Code:**
```php
$b = '<form action="' . esc_attr($this->build_action_url('reactivate')) . '" method="post" class="tnp-button-form tnp-reactivate">';
$b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';
```

**Fixed Code:**
```php
$b = '<form action="' . esc_attr($this->build_action_url('reactivate')) . '" method="post" class="tnp-button-form tnp-reactivate">';
$b .= wp_nonce_field('newsletter-reactivate', '_wpnonce', true, false);
$b .= '<input type="hidden" name="nk" value="' . esc_attr($this->get_user_key($user)) . '">';
```

**Explanation:**
Similar to the first vulnerability, the reactivation form was missing CSRF protection. The fix adds a nonce field with a different action identifier (`newsletter-reactivate`) to protect against CSRF attacks on the reactivation endpoint.

---

## Vulnerability 3

**Vulnerability Existed:** yes
TRUE POSITIVE

**Missing CSRF Token Validation - CWE-352 - unsubscription.php lines 142-145**

**Old Code:**
```php
case 'uc':

    $this->unsubscribe($user, $email);
```

**Fixed Code:**
```php
case 'uc':
    $verified = wp_verify_nonce($_REQUEST['_wpnonce'], 'newsletter-unsubscribe');
    if (!$verified) {
        $this->redirect($this->build_action_url('u', $user, $email));
    }
    $this->unsubscribe($user, $email);
```

**Explanation:**
The server-side handler for the unsubscription action was not validating the nonce token. The fix adds verification using `wp_verify_nonce()` which matches the action identifier sent in the form. If verification fails, the request is redirected rather than processed, preventing CSRF attacks.

---

## Vulnerability 4

**Vulnerability Existed:** not sure

**Inconsistent CSRF Token Validation - CWE-352 - unsubscription.php lines 161-165**

**Old Code:**
```php
case 'reactivate':
    $this->reactivate($user);
```

**Fixed Code:**
```php
case 'reactivate':
    $verified = wp_verify_nonce($_REQUEST['_wpnonce'], 'newsletter-unsubscribe');
    if (!$verified) {
        die('Unverified request');
    }
    $this->reactivate($user);
```

**Explanation:**
The fix adds nonce validation for the reactivate endpoint, which is good for CSRF protection. However, there's a potential inconsistency: the nonce action name is `'newsletter-unsubscribe'` but the form uses `'newsletter-reactivate'`. This mismatch would cause verification to fail for valid reactivation requests. This appears to be a bug in the fix itself - the nonce action should be `'newsletter-reactivate'` to match the form.

---

## Vulnerability 5

**Vulnerability Existed:** yes
TRUE POSITIVE

**Missing CSRF Token in Email Links - CWE-352 - unsubscription.php lines 247-251**

**Old Code:**
```php
function hook_newsletter_replace($text, $user, $email, $html = true) {
    if ($user) {
        $text = $this->replace_url($text, 'unsubscription_confirm_url', $this->build_action_url('uc', $user, $email));
        ...
        $text = $this->replace_url($text, 'reactivate_url', $this->build_action_url('reactivate', $user, $email));
```

**Fixed Code:**
```php
function hook_newsletter_replace($text, $user, $email, $html = true, $context = null) {
    if ($user) {
        $url = $this->build_action_url('uc', $user, $email);
        if ('page' === $context) {
            $url = wp_nonce_url($url, 'newsletter-unsubscribe');
        }
        $text = $this->replace_url($text, 'unsubscription_confirm_url', $url);
        ...
        $url = $this->build_action_url('reactivate', $user, $email);
        if ('page' === $context) {
            $url = wp_nonce_url($url, 'newsletter-reactivate');
        }
        $text = $this->replace_url($text, 'reactivate_url', $url);
```

**Explanation:**
The fix adds contextual nonce protection for URLs embedded in pages. When the context is 'page', the URLs are passed through `wp_nonce_url()` which adds nonce parameters to the URLs. This protects against CSRF attacks when users click links in emails or pages. The fix correctly uses matching action identifiers with the forms.
CVE Analysis Results:
CVE-2026-1051: Yes
View CVE Description
The Newsletter – Send awesome emails from WordPress plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 9.1.0. This is due to missing or incorrect nonce validation on the hook_newsletter_action() function. This makes it possible for unauthenticated attackers to unsubscribe newsletter subscribers via a forged request granted they can trick a logged-in user into performing an action such as clicking on a link.
Showing 1 to 1 of 1 results