mailauth
Version:
Email authentication library for Node.js
197 lines (169 loc) • 6.79 kB
Markdown
# SPF Verification Result Reference
This document describes the result object returned by the `spf()` function.
## Overview
The `spf` function verifies the SPF (Sender Policy Framework) record for an email sender and returns an object containing the verification result.
```javascript
const { spf } = require('mailauth/lib/spf');
const result = await spf({
sender: 'user.com',
ip: '192.0.2.1',
helo: 'mail.example.com',
mta: 'mx.receiver.com'
});
```
## Result Object Fields
| Field | Type | Presence | Description |
|-------|------|----------|-------------|
| `domain` | `string` | Always | The domain extracted from the sender address for SPF lookup |
| `client-ip` | `string` | Always | The client IP address that was checked |
| `helo` | `string` | If provided | The EHLO/HELO hostname from the SMTP session |
| `envelope-from` | `string` | If provided | The MAIL FROM address |
| `status` | `object` | Always | Verification status object (see below) |
| `header` | `string` | Always | Formatted Received-SPF header value |
| `info` | `string` | Always | Formatted Authentication-Results header value |
| `rr` | `string` | Record found | Raw SPF DNS TXT record |
| `lookups` | `object` | Always | DNS lookup statistics (see below) |
## status Object
| Field | Type | Description |
|-------|------|-------------|
| `result` | `string` | SPF result code (see below) |
| `comment` | `string` | Human-readable explanation of the result |
| `smtp` | `object` | SMTP session identifiers |
### status.smtp Object
| Field | Type | Description |
|-------|------|-------------|
| `mailfrom` | `string` | The MAIL FROM address |
| `helo` | `string` | The HELO/EHLO hostname |
## lookups Object
| Field | Type | Description |
|-------|------|-------------|
| `limit` | `number` | Maximum DNS lookups allowed (default: 10) |
| `count` | `number` | Number of DNS lookups performed |
| `void` | `number` | Number of void (empty result) DNS lookups |
| `subqueries` | `object` | Counts of DNS queries by type (e.g., `{A: 2, MX: 1}`) |
## Result Values
| Result | SPF Qualifier | Description |
|--------|---------------|-------------|
| `pass` | `+` | Sender is authorized |
| `fail` | `-` | Sender is explicitly not authorized |
| `softfail` | `~` | Sender is probably not authorized (transitional) |
| `neutral` | `?` | No policy assertion about the sender |
| `none` | - | No SPF record found or invalid domain |
| `permerror` | - | Permanent error (invalid SPF record, too many DNS lookups) |
| `temperror` | - | Temporary error (DNS timeout, server refused) |
## Comment Format
The `status.comment` field follows this format based on the result:
| Result | Comment Format |
|--------|----------------|
| `pass` | `"{mta}: domain of {sender} designates {ip} as permitted sender"` |
| `fail` | `"{mta}: domain of {sender} does not designate {ip} as permitted sender"` |
| `softfail` | `"{mta}: domain of transitioning {sender} does not designate {ip} as permitted sender"` |
| `neutral` | `"{mta}: {ip} is neither permitted nor denied by domain of {sender}"` |
| `none` | `"{mta}: {domain} does not designate permitted sender hosts"` |
| `permerror` | `"{mta}: permanent error in processing during lookup of {sender}: {text}"` |
| `temperror` | `"{mta}: error in processing during lookup of {sender}: {text}"` |
## Example Output
### SPF Pass
```json
{
"domain": "example.com",
"client-ip": "192.0.2.1",
"helo": "mail.example.com",
"envelope-from": "user@example.com",
"status": {
"result": "pass",
"comment": "mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender",
"smtp": {
"mailfrom": "user@example.com",
"helo": "mail.example.com"
}
},
"header": "Received-SPF: pass (mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender) client-ip=192.0.2.1;",
"info": "spf=pass (mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender) smtp.mailfrom=user@example.com smtp.helo=mail.example.com",
"rr": "v=spf1 ip4:192.0.2.0/24 -all",
"lookups": {
"limit": 10,
"count": 1,
"void": 0,
"subqueries": {}
}
}
```
### SPF Fail
```json
{
"domain": "example.com",
"client-ip": "203.0.113.1",
"helo": "attacker.example.net",
"envelope-from": "user@example.com",
"status": {
"result": "fail",
"comment": "mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender",
"smtp": {
"mailfrom": "user@example.com",
"helo": "attacker.example.net"
}
},
"header": "Received-SPF: fail (mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender) client-ip=203.0.113.1;",
"info": "spf=fail (mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender) smtp.mailfrom=user@example.com smtp.helo=attacker.example.net",
"rr": "v=spf1 ip4:192.0.2.0/24 -all",
"lookups": {
"limit": 10,
"count": 1,
"void": 0,
"subqueries": {}
}
}
```
### SPF None (No Record)
```json
{
"domain": "no-spf.example.com",
"client-ip": "192.0.2.1",
"helo": "mail.no-spf.example.com",
"envelope-from": "user@no-spf.example.com",
"status": {
"result": "none",
"comment": "mx.receiver.com: no-spf.example.com does not designate permitted sender hosts",
"smtp": {
"mailfrom": "user@no-spf.example.com",
"helo": "mail.no-spf.example.com"
}
},
"header": "Received-SPF: none (mx.receiver.com: no-spf.example.com does not designate permitted sender hosts) client-ip=192.0.2.1;",
"info": "spf=none (mx.receiver.com: no-spf.example.com does not designate permitted sender hosts) smtp.mailfrom=user@no-spf.example.com smtp.helo=mail.no-spf.example.com",
"lookups": {
"limit": 10,
"count": 1,
"void": 1,
"subqueries": {}
}
}
```
### SPF Permerror (Too Many Lookups)
```json
{
"domain": "complex.example.com",
"client-ip": "192.0.2.1",
"envelope-from": "user@complex.example.com",
"status": {
"result": "permerror",
"comment": "mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests",
"smtp": {
"mailfrom": "user@complex.example.com"
}
},
"header": "Received-SPF: permerror (mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests) client-ip=192.0.2.1;",
"info": "spf=permerror (mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests) smtp.mailfrom=user@complex.example.com",
"lookups": {
"limit": 10,
"count": 11,
"void": 0,
"subqueries": {
"include": 5,
"a": 3,
"mx": 2
}
}
}
```