Lumen Payroll: visibility and experience audit
lumenpayroll.com, audited 9 Oct 2026
Domain trust for lumenpayroll.com
- HTTPS and TLS
- 87goodTLSv1.3, certificate 83 days left
- Security headers
- 5poorMDN Observatory grade F
- Email authentication
- 37poorSPF missing, DMARC missing
- JavaScript libraries
- 85good3 detected, 1 vulnerable
Passive checks only: the same requests a visitor’s browser and a receiving mail server make. Nothing is probed, scanned or logged in to. Findings describe what was observed; they are not a security certification.
Findings
- highmeasured
No SPF record on lumenpayroll.com
TXT lumenpayroll.com: no v=spf1 record. MX: aspmx.l.google.com, alt1.aspmx.l.google.com, alt2.aspmx.l.google.com, alt3.aspmx.l.google.com, alt4.aspmx.l.google.com
Why it matters: Receivers cannot tell which servers may send mail as this domain, so legitimate mail is more likely to land in spam and spoofed mail is more likely to be delivered. Since February 2024 Gmail and Yahoo require bulk senders (5,000+ messages a day to their users) to publish SPF and DKIM, a DMARC policy (p=none at minimum) aligned with the From domain, and one-click unsubscribe; since 5 May 2025 Microsoft (Outlook.com, Hotmail, Live) applies the same SPF, DKIM and DMARC requirements and rejects non-compliant bulk mail. Smaller senders are increasingly filtered on the same signals.
Fix: Publish one SPF record listing every service that sends as lumenpayroll.com (add your newsletter/CRM provider's include too).
Show the code
Type: TXT Name: lumenpayroll.com Value: v=spf1 include:_spf.google.com ~all TTL: 3600 ; zone-file form lumenpayroll.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all"
lumenpayroll.comeffort Sworker/trust (node:dns)trust.email.spf_missing - highmeasured
No DMARC record on lumenpayroll.com
TXT _dmarc.lumenpayroll.com: no v=DMARC1 record
Why it matters: DMARC tells receivers what to do with mail that fails SPF/DKIM alignment and sends you reports of who is sending as your domain. Without it, anyone can spoof the From address. Since February 2024 Gmail and Yahoo require bulk senders (5,000+ messages a day to their users) to publish SPF and DKIM, a DMARC policy (p=none at minimum) aligned with the From domain, and one-click unsubscribe; since 5 May 2025 Microsoft (Outlook.com, Hotmail, Live) applies the same SPF, DKIM and DMARC requirements and rejects non-compliant bulk mail. Smaller senders are increasingly filtered on the same signals.
Fix: Start in monitoring mode, read the reports for 2–4 weeks, then move to p=quarantine and p=reject.
Show the code
Type: TXT Name: _dmarc.lumenpayroll.com Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@lumenpayroll.com; adkim=r; aspf=r; fo=1 TTL: 3600 ; zone-file form _dmarc.lumenpayroll.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@lumenpayroll.com; adkim=r; aspf=r; fo=1"
lumenpayroll.comeffort Sworker/trust (node:dns)trust.email.dmarc_missing - mediummeasured
HSTS is switched off (max-age=0)
strict-transport-security: max-age=0 — max-age=0 (0 days) is under one year; includeSubDomains is missing; preload is missing
Why it matters: A max-age of at least one year with includeSubDomains is the hstspreload.org requirement; under six months is penalised by MDN Observatory (hsts-implemented-max-age-less-than-six-months, −10).
Fix: Once every subdomain serves HTTPS, send.
Show the code
# nginx (server block) add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # Apache (.htaccess or vhost, mod_headers) Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Strict-Transport-Security: max-age=63072000; includeSubDomains; preload # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Strict-Transport-Security = max-age=63072000; includeSubDomains; preload then submit the domain at https://hstspreload.org.lumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.hsts.weak - mediummeasured
No Content-Security-Policy
No content-security-policy header or <meta http-equiv> on the home page.
Why it matters: A CSP is the main browser defence against injected scripts (XSS) and malicious third-party code. (MDN Observatory: csp-not-implemented, −25.)
Fix: Start in report-only mode, fix what it reports, then enforce. A starting policy.
Show the code
# nginx (server block) add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests" always; # Apache (.htaccess or vhost, mod_headers) Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Content-Security-Policy-Report-Only", value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Content-Security-Policy-Report-Only = default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests Add every third-party origin your pages load (analytics, fonts, embeds) to the matching directive.lumenpayroll.com/effort Mworker/trust (MDN Observatory rules)trust.headers.csp_missing - mediummeasured
The page can be framed by any site (no X-Frame-Options or CSP frame-ancestors)
x-frame-options: (absent); CSP frame-ancestors: absent
Why it matters: Another site can load this page invisibly in a frame and trick visitors into clicking (clickjacking). (MDN Observatory: x-frame-options-not-implemented, −20.)
Fix: Send either header (both is fine).
Show the code
# nginx (server block) add_header Content-Security-Policy "frame-ancestors 'self'" always; # Apache (.htaccess or vhost, mod_headers) Header always set Content-Security-Policy "frame-ancestors 'self'" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Content-Security-Policy", "value": "frame-ancestors 'self'" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Content-Security-Policy", value: "frame-ancestors 'self'" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Content-Security-Policy: frame-ancestors 'self' # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Content-Security-Policy = frame-ancestors 'self' # nginx (server block) add_header X-Frame-Options "SAMEORIGIN" always; # Apache (.htaccess or vhost, mod_headers) Header always set X-Frame-Options "SAMEORIGIN" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "X-Frame-Options", "value": "SAMEORIGIN" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "X-Frame-Options", value: "SAMEORIGIN" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* X-Frame-Options: SAMEORIGIN # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # X-Frame-Options = SAMEORIGINlumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.headers.clickjacking - mediummeasured
moment.js 2.30.1 has 1 known vulnerability
https://static.lumenpayroll.com/universal/scripts-compressed/extract-css-moment-js-vendor-a5cfdec1ae227f33-min.en-US.js (detected by filecontent). CVE-2026-17495, GHSA-4p3w-j4w9-5jqw. moment vulnerable to Path Traversal via crafted non-string locale name
Why it matters: Automated scanners fingerprint library versions and try the published exploits. Whether a given flaw is reachable depends on how the page uses the library, so treat this as an upgrade task rather than proof of compromise.
Fix: Upgrade moment.js to 2.31.0 or later (npm: npm install moment@latest; CDN: change the version in the script URL). Check the changelog for breaking changes. This file is served by the site platform, so the upgrade is the platform's to make; report it to them.
static.lumenpayroll.com/universal/scripts-compressed/extract-css-moment-js-vendor-a5cfdec1ae227f33-min.en-US.jseffort Mworker/trust (retire.js repository)trust.libraries.vulnerable - lowmeasured
10 third-party scripts use protocol-relative URLs (//host/…)
//use.typekit.net/ik/55ov5wGkYOpoENT-j9tEc6YgGNMD54Cfz1TpzvTBUyvfeGSgfFHN4UJLFRbh52jhWDmcjRwXw29DwQJa5QiRFcZRZ2SD5ejajsG, //static.lumenpayroll.com/@sqs/polyfiller/1.7.7/modern.js, //static.lumenpayroll.com/universal/scripts-compressed/visitor-site-error-reporter-e9c24af58b4efe13-min.en-US.js, //static.lumenpayroll.com/universal/scripts-compressed/extract-css-runtime-fde12d4f2db1af19-min.en-US.js, //static.lumenpayroll.com/universal/scripts-compressed/extract-css-moment-js-vendor-a5cfdec1ae227f33-min.en-US.js
Why it matters: On this HTTPS page they load over HTTPS, but the same markup served over HTTP would load them insecurely; MDN Observatory therefore scores them as not loaded securely (MDN Observatory: sri-not-implemented-and-external-scripts-not-loaded-securely, -50.)
Fix: Write the scheme explicitly: src="https://host/…" instead of src="//host/…" (platform-generated tags, e.g. on the site builder, may not be editable).
lumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.headers.protocol_relative_scripts - lowmeasured
No MTA-STS policy
TXT _mta-sts.lumenpayroll.com: none
Why it matters: Mail between servers falls back to unencrypted delivery when TLS fails or is stripped; MTA-STS (RFC 8461) tells senders to require TLS to your MX hosts.
Fix: Paste the matching snippet for your setup.
Show the code
Type: TXT Name: _mta-sts.lumenpayroll.com Value: v=STSv1; id=20261020231447 TTL: 3600 ; zone-file form _mta-sts.lumenpayroll.com. 3600 IN TXT "v=STSv1; id=20261020231447" # Serve this file at https://mta-sts.lumenpayroll.com/.well-known/mta-sts.txt (HTTPS, valid certificate, no redirects) version: STSv1 mode: testing mx: aspmx.l.google.com mx: alt1.aspmx.l.google.com mx: alt2.aspmx.l.google.com mx: alt3.aspmx.l.google.com mx: alt4.aspmx.l.google.com max_age: 604800 # then switch mode: testing → enforce after a week of clean TLS-RPT reports
lumenpayroll.comeffort Mworker/trust (node:dns)trust.email.mta_sts_missing - lowmeasured
No CAA record (any CA may issue certificates)
CAA lookup from lumenpayroll.com up to lumenpayroll.com: none
Why it matters: CAA (RFC 8659) lists the certificate authorities allowed to issue for the domain; every public CA must check it, which blocks mis-issuance by any other CA.
Fix: ; your current certificate is from Let's Encrypt / YR2
Show the code
lumenpayroll.com. 3600 IN CAA 0 issue "letsencrypt.org" lumenpayroll.com. 3600 IN CAA 0 iodef "mailto:security@lumenpayroll.com"
lumenpayroll.comeffort Sworker/trust (node:dns)trust.dns.caa_missing - infomeasured
No Referrer-Policy header
referrer-policy: (absent)
Why it matters: Without a policy, older browsers send the full URL (including query strings that may hold IDs or tokens) to every third party. Modern browsers default to strict-origin-when-cross-origin. (MDN Observatory: referrer-policy-not-implemented, 0; setting a private policy earns +5.)
Fix: Paste the matching snippet for your setup.
Show the code
# nginx (server block) add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Apache (.htaccess or vhost, mod_headers) Header always set Referrer-Policy "strict-origin-when-cross-origin" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Referrer-Policy: strict-origin-when-cross-origin # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Referrer-Policy = strict-origin-when-cross-originlumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.headers.referrer_policy - infomeasured
No Permissions-Policy header
permissions-policy: (absent)
Why it matters: Permissions-Policy switches off powerful browser features (camera, microphone, geolocation, payment) the site does not use, so an injected or third-party script cannot request them. Not scored by MDN Observatory.
Fix: Paste the matching snippet for your setup.
Show the code
# nginx (server block) add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" always; # Apache (.htaccess or vhost, mod_headers) Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=() # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Permissions-Policy = camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()lumenpayroll.com/effort Sworker/trusttrust.headers.permissions_policy - infomeasured
No Cross-Origin-Opener-Policy
cross-origin-opener-policy: (absent)
Why it matters: COOP isolates the page from windows it opens or that open it, blocking cross-window attacks (XS-Leaks, tabnabbing). (MDN Observatory: coop-not-implemented, 0; same-origin earns +10.)
Fix: Paste the matching snippet for your setup.
Show the code
# nginx (server block) add_header Cross-Origin-Opener-Policy "same-origin-allow-popups" always; # Apache (.htaccess or vhost, mod_headers) Header always set Cross-Origin-Opener-Policy "same-origin-allow-popups" # Vercel (vercel.json) { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Cross-Origin-Opener-Policy", "value": "same-origin-allow-popups" } ] } ] } # Next.js (next.config.js) async headers() { return [{ source: "/(.*)", headers: [{ key: "Cross-Origin-Opener-Policy", value: "same-origin-allow-popups" }] }]; } # Cloudflare Pages / Netlify (_headers file) /* Cross-Origin-Opener-Policy: same-origin-allow-popups # Cloudflare (proxied sites): Rules > Transform Rules > Modify Response Header > Set static # Cross-Origin-Opener-Policy = same-origin-allow-popups (use same-origin if the site never relies on popups such as OAuth or payment windows talking back to it)lumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.headers.coop - infomeasured
1 cookie without a SameSite attribute
crumb=<redacted>;Secure;Path=/
Why it matters: Browsers default missing SameSite to Lax, but being explicit protects older browsers against cross-site request forgery; anti-CSRF cookies without it are penalised by MDN Observatory (cookies-anticsrf-without-samesite-flag, −20).
Fix: Add SameSite=Lax (or Strict for cookies never needed on cross-site navigation).
lumenpayroll.com/effort Sworker/trust (MDN Observatory rules)trust.cookies.no_samesite - infomeasured
No DKIM key found on common selectors
Probed google._domainkey.lumenpayroll.com, selector1._domainkey.lumenpayroll.com, selector2._domainkey.lumenpayroll.com, k1._domainkey.lumenpayroll.com … (19 selectors). DKIM may still be configured on a selector we did not try; selectors are only visible in a signed message's DKIM-Signature header (s=).
Why it matters: DKIM signs each message so receivers can verify it was not altered and that the domain sent it. Since February 2024 Gmail and Yahoo require bulk senders (5,000+ messages a day to their users) to publish SPF and DKIM, a DMARC policy (p=none at minimum) aligned with the From domain, and one-click unsubscribe; since 5 May 2025 Microsoft (Outlook.com, Hotmail, Live) applies the same SPF, DKIM and DMARC requirements and rejects non-compliant bulk mail. Smaller senders are increasingly filtered on the same signals.
Fix: Check a message you sent (Show original → DKIM-Signature s=…). If DKIM is off, enable it in your mail provider (Google Workspace: Admin › Apps › Gmail › Authenticate email; Microsoft 365: Defender › Email authentication › DKIM) and publish the TXT/CNAME it gives you.
lumenpayroll.comeffort Sworker/trust (node:dns)trust.email.dkim_not_found - infomeasured
No TLS-RPT record
TXT _smtp._tls.lumenpayroll.com: none
Why it matters: TLS-RPT (RFC 8460) makes senders report failed encrypted deliveries to you, which is how you learn MTA-STS or certificate problems are dropping mail.
Fix: Paste the matching snippet for your setup.
Show the code
Type: TXT Name: _smtp._tls.lumenpayroll.com Value: v=TLSRPTv1; rua=mailto:tlsrpt@lumenpayroll.com TTL: 3600 ; zone-file form _smtp._tls.lumenpayroll.com. 3600 IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@lumenpayroll.com"
lumenpayroll.comeffort Sworker/trust (node:dns)trust.email.tls_rpt_missing
Email authentication
- MX
- aspmx.l.google.com, alt1.aspmx.l.google.com, alt2.aspmx.l.google.com, alt3.aspmx.l.google.com, alt4.aspmx.l.google.com
- SPF
- missing
- SPF DNS lookups
- 0 of 10 allowed
- DMARC
- missing
- DKIM
- not found on 19 common selectors (it may use another)
- MTA-STS
- not set
- TLS-RPT
- not set
- BIMI
- not set
HTTPS, certificate and headers
- HTTP to HTTPS
- http unavailable
- HSTS
max-age=0- Certificate
- Let's Encrypt / YR2; valid until 2027-01-12T17:07:50.000Z; trusted
- Legacy TLS 1.0/1.1
- refused
- Content-Security-Policy
- missing
- Cookies on the home page
- 1 (0 without Secure, 1 without SameSite)
- CAA records
- none
JavaScript libraries
- moment.js 2.30.1 1 known vulnerability (CVE-2026-17495, GHSA-4p3w-j4w9-5jqw)
- YUI 3.17.2 no known vulnerabilities
- lodash 4.18.1 no known vulnerabilities