Skip to content

Commit 2d7b971

Browse files
committed
fix: sanitize envelope size to prevent SMTP command injection
Cast envelope.size to a number before concatenating into the MAIL FROM command, preventing CRLF injection of arbitrary SMTP commands.
1 parent 4e702e9 commit 2d7b971

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

lib/smtp-connection/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,10 @@ class SMTPConnection extends EventEmitter {
11591159
}
11601160

11611161
if (this._envelope.size && this._supportedExtensions.includes('SIZE')) {
1162-
args.push('SIZE=' + this._envelope.size);
1162+
const sizeValue = Number(this._envelope.size) || 0;
1163+
if (sizeValue > 0) {
1164+
args.push('SIZE=' + sizeValue);
1165+
}
11631166
}
11641167

11651168
// If the server supports DSN and the envelope includes an DSN prop

test/smtp-connection/smtp-connection-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,24 @@ describe('SMTP-Connection Tests', () => {
13951395
);
13961396
});
13971397

1398+
it('should sanitize CRLF in envelope size to prevent SMTP injection', (t, done) => {
1399+
client.send(
1400+
{
1401+
from: 'test@valid.sender',
1402+
to: ['test@valid.recipient'],
1403+
size: '100\r\nRCPT TO:<attacker@evil.com>'
1404+
},
1405+
'test',
1406+
(err, info) => {
1407+
assert.ok(!err);
1408+
assert.deepStrictEqual(info.accepted, ['test@valid.recipient']);
1409+
assert.ok(!info.accepted.includes('attacker@evil.com'));
1410+
assert.ok(!info.rejected.includes('attacker@evil.com'));
1411+
done();
1412+
}
1413+
);
1414+
});
1415+
13981416
it('should return error for no valid recipients', (t, done) => {
13991417
client.send(
14001418
{

0 commit comments

Comments
 (0)