Email security · Practical guide

Investigate a hosting renewal email with header and URL checks

Inspect an email source offline, parse its real destination hostname and verify billing through a known portal before acting on a renewal notice.

Archive placement: November 2022

A padlock and keys on a keyboard

A fraudulent renewal notice can imitate a registrar, hosting provider or certificate warning closely enough to create urgency. The safest verification path is an existing bookmark or independently known portal. Header and URL inspection can explain suspicious details, but neither a polished design nor an authentication pass proves that a payment request is legitimate.

Verify the account event through an independent route

Open your provider's portal from a saved bookmark or your own account records and look for the matching invoice, domain and renewal date. Do not use the message's phone number or support link to validate the same message. If something is unclear, contact the provider through a known channel.

Separate a domain registration renewal from hosting, DNS, email and optional listing services. A notice about search submission or a directory entry may resemble a required domain renewal while actually selling something unrelated. Check the service description and the legal supplier before paying.

A request to change bank details or move payment outside the normal portal deserves separate verification using an established contact. Avoid forwarding the message around with active links and asking colleagues to try them.

Inspect the saved message without rendering its content

Read selected headers from a saved .eml file offline
from email import policy
from email.parser import BytesParser
from pathlib import Path

message = BytesParser(policy=policy.default).parsebytes(
    Path("suspect.eml").read_bytes()
)
for field in ("From", "Reply-To", "Return-Path", "Subject", "Date",
              "Authentication-Results", "Received"):
    for value in message.get_all(field, []):
        print(f"{field}: {value!r}")

The repr-style output helps expose unusual characters rather than rendering HTML or executing attachment content. Compare the actual address domains and Reply-To with the provider's known identity. A familiar display name is just message text and can be chosen by the sender.

Received and Authentication-Results headers require context. Attackers can insert misleading headers before a message reaches your trusted receiving infrastructure. Interpret the results added by your receiving service and its documented trust boundary, rather than accepting every pass string present in the file.

Parse the destination hostname instead of reading the visible label

Examine a URL as text without making a request
from urllib.parse import urlsplit

candidate = "https://billing.example.com.account-check.invalid/login"
parts = urlsplit(candidate)
print("scheme:", repr(parts.scheme))
print("hostname:", repr(parts.hostname))
print("port:", parts.port)
print("contains user information:", parts.username is not None)
print("path:", repr(parts.path))

The hostname in this example belongs under account-check.invalid, not example.com. A brand name at the start of a longer hostname is not proof of ownership. Also inspect user-information tricks, shortened links and internationalized domain names carefully; a parser extracts components but does not decide who owns a domain or whether a page is trustworthy.

Do not paste real signed login links or password-reset tokens into public scanners. Query strings can grant access, identify a customer or leak confidential details. The independent portal route is usually more useful than trying to make a questionable link safe to visit.

Understand what email authentication can and cannot establish

SPF checks an authorized sending path for a specific envelope identity, DKIM verifies a signature associated with a signing domain, and DMARC checks alignment with the visible From domain. A lookalike domain can pass all three for itself. A compromised legitimate account can also send authenticated fraud.

Authentication failures can support an investigation, but forwarding and configuration errors can complicate the result. Use the billing record, actual domain identity and trusted provider contact together. Do not build a rule that automatically pays any invoice whose message says dmarc=pass.

Respond according to what happened

  • If you only received the message, preserve or report it through your organization's phishing process.
  • If you entered a password, use a trusted device to rotate it and revoke sessions and tokens at the real service.
  • If you approved MFA or changed recovery settings, review those settings and tell the provider what was approved.
  • If money was sent, contact your payment provider and the genuine supplier promptly through verified channels.

Opening a link does not establish exactly what data was exposed. Record the time, device and actions taken, and let the incident response process determine the next checks. Do not submit additional information to the suspicious site to see whether it works.

Reduce the chance of the next successful attempt

Use a password manager that recognizes the intended hostname and phishing-resistant MFA where available. Document who can approve hosting and domain payments, and keep service renewal dates in the real account inventory. Train staff to verify urgent changes through a separate known route.

Retain useful evidence in a protected location and redact personal data before sharing it. A repeatable verification procedure is more dependable than trying to memorize every possible visual sign of a fake message.

Primary documentation

← Back to all guidesDiscuss your hosting setup ↗