GitHub Security Advisory: GHSA-c7w3-x93f-qmm8
Package: nodemailer (NPM)
Severity: LOW (CVSS 0.0)
CWE: CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')
Vulnerable versions: < 8.0.4
Patched in: 8.0.4

Summary: Nodemailer has SMTP command injection due to unsanitized `envelope.size` parameter

Details:
### Summary
When a custom `envelope` object is passed to `sendMail()` with a `size` property containing CRLF characters (`\r\n`), the value is concatenated directly into the SMTP `MAIL FROM` command without sanitization. This allows injection of arbitrary SMTP commands, including `RCPT TO` — silently adding attacker-controlled recipients to outgoing emails.


### Details
In `lib/smtp-connection/index.js` (lines 1161-1162), the `envelope.size` value is concatenated into the SMTP `MAIL FROM` command without any CRLF sanitization:

```javascript
if (this._envelope.size && this._supportedExtensions.includes('SIZE')) {
    args.push('SIZE=' + this._envelope.size);
}
```

This contrasts with other envelope parameters in the same function that ARE properly sanitized:
- **Addresses** (`from`, `to`): validated for `[\r\n<>]` at lines 1107-1127
- **DSN parameters** (`dsn.ret`, `dsn.envid`, `dsn.orcpt`): encoded via `encodeXText()` at lines 1167-1183

The `size` property reaches this code path through `MimeNode.setEnvelope()` in `lib/mime-node/index.js` (lines 854-858), which copies all non-standard envelope properties verbatim:

```javascript
const standardFields = ['to', 'cc', 'bcc', 'from'];
Object.keys(envelope).forEach(key => {
    if (!standardFields.includes(key)) {
        this._envelope[key] = envelope[key];
    }
});
```

Since `_sendCommand()` writes the command string followed by `\r\n` to the raw TCP socket, a CRLF in the `size` value terminates the `MAIL FROM` command and starts a new SMTP command.

Note: by default, Nodemailer constructs the envelope automatically from the message's `from`/`to` fields and does not include `size`. This vulnerability requires the application to explicitly pass a custom `envelope` object with a `size` property to `sendMail()`. 
While this limits the attack surface, applications that expose envelope configuration to users are affected.

### PoC
ave the following as `poc.js` and run with `node poc.js`:

```javascript
const net = require('net');
const nodemailer = require('nodemailer');

// Minimal SMTP server that logs raw commands
const server = net.createServer(socket => {
    socket.write('220 localhost ESMTP\r\n');
    let buffer = '';
    socket.on('data', chunk => {
        buffer += chunk.toString();
        const lines = buffer.split('\r\n');
        buffer = lines.pop();
        for (const line of lines) {
            if (!line) continue;
            console.log('C:', line);
            if (line.startsWith('EHLO')) {
                socket.write('250-localhost\r\n250-SIZE 10485760\r\n250 OK\r\n');
            } else if (line.startsWith('MAIL FROM')) {
                socket.write('250 OK\r\n');
            } else if (line.startsWith('RCPT TO')) {
                socket.write('250 OK\r\n');
            } else if (line === 'DATA') {
                socket.write('354 Start\r\n');
            } else if (line === '.') {
                socket.write('250 OK\r\n');
            } else if (line.startsWith('QUIT'))