From b2908622f04e1cac03e7279bd4fd67b3b97176fa Mon Sep 17 00:00:00 2001 From: Steve Freegard Date: Tue, 19 Nov 2024 09:42:20 +0000 Subject: [PATCH] Fix undefined variable exception when no MX is found and add spf_record_include_match property (#32) Changes proposed in this pull request: - Fix crash in mech_mx code, caused by undefined variable if no valid MXs are found: ````` SPF error: domain sampark.gov.in Cannot read properties of undefined (reading 'join') TypeError: Cannot read properties of undefined (reading 'join') at SPF.mech_mx (/app/node_modules/haraka-plugin-spf/lib/spf.js:523:59) at async SPF.check_host (/app/node_modules/haraka-plugin-spf/lib/spf.js:307:22) at async cachedSPFLookup (/app/processors/dblack/index.js:26:27) at async Processor.process (/app/processors/dblack/index.js:122:20) at async /app/processors/lib/lib.js:813:11 at async #process (/app/processors/lib/lib.js:808:12) ````` - Add new `spf_record_include_match` property to allow for additional filtering e.g. find includes that allow larges swathes of IPv4 space: ````` source_ip=95.79.45.75 domain="moduineffectua.com" spfRecord="v=spf1 include:_so.moduineffectua.com include:_vz.moduineffectua.com include:_v.moduineffectua.com ~all" match_include="v=spf1 ip4:0.0.0.0/5 ip4:8.0.0.0/7 ip4:11.0.0.0/8 ip4:12.0.0.0/6 ip4:16.0.0.0/4 ip4:32.0.0.0/3 ip4:64.0.0.0/2 ip4:128.0.0.0/3 ip4:160.0.0.0/5 ip4:168.0.0.0/6 ~all" include_domain="_so.moduineffectua.com" ````` Checklist: - [X] docs updated - [X] tests updated - [X] Changes.md updated --- CHANGELOG.md | 3 +++ lib/spf.js | 8 +++++++- test/spf.js | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d83d3d2..489baf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### Unreleased +- fix: undefined variable in mech_mx if no valid MX found +- add: new spf_record_include_match property to allow for additional filtering + ### [1.2.8] - 2024-10-07 - fix: mech_MX crit error on logging undef addrs diff --git a/lib/spf.js b/lib/spf.js index 8cd40f0..db0f3a2 100644 --- a/lib/spf.js +++ b/lib/spf.js @@ -13,6 +13,9 @@ class SPF { this.helo = 'unknown' this.spf_record = '' + // Store any matching include record for analysis + this.spf_record_include_match = {} + // RFC 4408 Section 10.1 // Limit the number of mechanisms/modifiers that require DNS lookups to complete. this.count = 0 @@ -358,6 +361,9 @@ class SPF { ) switch (result) { case this.SPF_PASS: + // Store matching "include" mechanisms + this.spf_record_include_match = { ...this.spf_record_include_match, ...recurse.spf_record_include_match } + this.spf_record_include_match[domain] = recurse.spf_record return this.SPF_PASS case this.SPF_FAIL: case this.SPF_SOFTFAIL: @@ -506,7 +512,7 @@ class SPF { resolve_method = 'resolve6' } - let addrs + let addrs = []; try { addrs = await dns[resolve_method](mx) } catch (err) { diff --git a/test/spf.js b/test/spf.js index fe2450d..f79241f 100644 --- a/test/spf.js +++ b/test/spf.js @@ -107,4 +107,11 @@ describe('SPF', function () { assert.equal(this.SPF.valid_ip(':212.70.d.94'), false) done() }) + + it('sets spf_record_include_match correctly', async function () { + this.timeout = 3000 + this.SPF.count = 0 + await this.SPF.check_host('130.211.0.1', 'google.com') + assert.ok(this.SPF.spf_record_include_match?.['_netblocks3.google.com'], 'expected include not found') + }) })