VYPR
Moderate severityNVD Advisory· Published Feb 21, 2026· Updated Feb 24, 2026

Lettermint Node.js SDK leaks email properties to unintended recipients when client instance is reused

CVE-2026-27492

Description

Lettermint Node.js SDK is the official Node.js SDK for Lettermint. In versions 1.5.0 and below, email properties (such as to, subject, html, text, and attachments) are not reset between sends when a single client instance is reused across multiple .send() calls. This can cause properties from a previous send to leak into a subsequent one, potentially delivering content or recipient addresses to unintended parties. Applications sending emails to different recipients in sequence — such as transactional flows like password resets or notifications — are affected. This issue has been fixed in version 1.5.1.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Lettermint Node.js SDK ≤1.5.0 fails to reset email properties between sends, causing data leak across recipients in transactional flows.

Vulnerability

Analysis

CVE-2026-27492 is a property persistence flaw in the Lettermint Node.js SDK (versions ≤1.5.0) that affects the fluent email builder interface. When a single emailEndpoint instance is reused across multiple .send() calls, mutable properties (e.g., to, subject, html, text, cc, bcc, replyTo, headers, attachments, route, metadata, tag, idempotencyKey) are not reset between sends [1][2]. This means that properties set in a previous .send() invocation persist into subsequent ones unless explicitly overwritten.

Exploitation

Scenario

This bug is exploitable in any application that creates one SDK client object and reuses it to send emails to different recipients sequentially—common in transactional email flows such as password resets, notifications, or confirmations [1]. An attacker would not need special privileges beyond triggering the vulnerable code path. For example, if a server sends a password reset email to user A, then immediately sends a different email to user B using the same client instance, user B might receive user A's intended content, attachments, or even recipient address fields [2]. The attack surface is server-side but can lead to inadvertent disclosure of sensitive information to unintended recipients.

Impact

A successful exploit can result in delivery of email content, subject lines, attachments, or recipient addresses to wrong parties. This could leak personally identifiable information (PII), authentication tokens (e.g., password reset links), or confidential business data [1]. The severity is heightened in applications that handle sensitive operations sequentially without intervening property resets.

Mitigation

The fix was released in version 1.5.1, which implements a reset() call inside a finally block to guarantee cleanup of all payload properties after every .send(), even if the send operation fails [2][4]. Users should immediately update to >=1.5.1. As a workaround, applications can manually reinitialize all properties before each send or maintain separate client instances per email, though these workarounds are error-prone and not recommended over updating [1].

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
lettermintnpm
< 1.5.11.5.1

Affected products

2

Patches

1
24a17acbc242

fix: reset email properties after each send

https://github.com/lettermint/lettermint-nodeBjarn BronsveldFeb 20, 2026via ghsa
2 files changed · +83 1
  • src/endpoints/email.spec.ts+66 0 modified
    @@ -316,6 +316,72 @@ describe('EmailEndpoint', () => {
         );
       });
     
    +  it('should reset all payload properties after send', async () => {
    +    // First email with all properties set
    +    await emailEndpoint
    +      .from('sender@example.com')
    +      .to('recipient@example.com')
    +      .subject('First Subject')
    +      .html('<p>First</p>')
    +      .text('First')
    +      .cc('cc@example.com')
    +      .bcc('bcc@example.com')
    +      .replyTo('reply@example.com')
    +      .headers({ 'X-Custom': 'Value' })
    +      .attach('file.txt', 'base64content')
    +      .route('first-route')
    +      .metadata({ key: 'value' })
    +      .tag('first-tag')
    +      .idempotencyKey('key-1')
    +      .send();
    +
    +    // Second email with only required properties
    +    await emailEndpoint
    +      .from('other@example.com')
    +      .to('other-recipient@example.com')
    +      .subject('Second Subject')
    +      .text('Second')
    +      .send();
    +
    +    // Verify second email does NOT contain any properties from the first
    +    expect(client.post).toHaveBeenLastCalledWith(
    +      '/send',
    +      {
    +        from: 'other@example.com',
    +        to: ['other-recipient@example.com'],
    +        subject: 'Second Subject',
    +        text: 'Second',
    +      },
    +      undefined
    +    );
    +  });
    +
    +  it('should not accumulate attachments across sends', async () => {
    +    await emailEndpoint
    +      .from('sender@example.com')
    +      .to('recipient@example.com')
    +      .subject('First')
    +      .text('First')
    +      .attach('file1.txt', 'content1')
    +      .send();
    +
    +    await emailEndpoint
    +      .from('sender@example.com')
    +      .to('recipient@example.com')
    +      .subject('Second')
    +      .text('Second')
    +      .attach('file2.txt', 'content2')
    +      .send();
    +
    +    expect(client.post).toHaveBeenLastCalledWith(
    +      '/send',
    +      expect.objectContaining({
    +        attachments: [{ filename: 'file2.txt', content: 'content2' }],
    +      }),
    +      undefined
    +    );
    +  });
    +
       it('should set the idempotency key in the request headers', async () => {
         // Set up a basic email with an idempotency key
         emailEndpoint
    
  • src/endpoints/email.ts+17 1 modified
    @@ -338,6 +338,22 @@ export class EmailEndpoint extends Endpoint {
           ? { headers: { 'Idempotency-Key': this.idempotencyKeyValue } }
           : undefined;
     
    -    return this.httpClient.post<SendEmailResponse>('/send', this.payload, config);
    +    const response = await this.httpClient.post<SendEmailResponse>('/send', this.payload, config);
    +
    +    this.reset();
    +
    +    return response;
    +  }
    +
    +  /**
    +   * Reset the payload and idempotency key to their initial state
    +   */
    +  private reset(): void {
    +    this.payload = {
    +      from: '',
    +      to: [],
    +      subject: '',
    +    };
    +    this.idempotencyKeyValue = undefined;
       }
     }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

1