RoastMyOpsec

News

security.txt Expires vs Stale Contact for Public Sites

September 15, 2025

security.txt Expires vs a stale Contact for public sites is a freshness decision versus an intake-mailbox decision: RFC 9116 requires an Expires timestamp so parsers know the file is still intended, while Contact is the URL or email researchers should use. A file with a future Expires and a mailbox nobody reads is worse than omitting security.txt. RoastMyOpsec does not require security.txt and does not score a missing or expired file as a standalone F.

The practical difference

RFC 9116 security.txt lives at /.well-known/security.txt. Contact and Expires are the core fields. Policy, Acknowledgments, Canonical, and Encryption are optional. Expires is not a certificate; it is how you promise the file is still current. After that date, consumers should treat the file as stale.

Stale Contact is the human failure: intern@, a departed employee, a Google Group that auto-expires, or a ticket form that 404s. Researchers who follow a dead Contact waste time or go public. humans.txt is not an alternate parser location. A /security HTML page can still help humans; the machine file still needs a live Contact.

Publishing security.txt is a commitment to read it. If legal will not let you, do not ship a decorative file with a personal Gmail and a two-year Expires.

How to choose based on what you shipped

If you will triaging reports: ship security.txt with a monitored alias, a realistic Expires you will renew, and Canonical if you mirror hosts. If you will not read reports: omit the file rather than lie. Do not put the only Contact in humans.txt or a blog RSS item.

OptionWhen it winsWatch-outTakeaway
Fresh Expires + live ContactYou will actually read reportsForgetting to renew ExpiresThis is a working disclosure file
Expired security.txtIt does not — parsers should ignore itLeaving Contact that still looks officialRenew or remove
No security.txtYou will not staff an inboxResearchers guessing webmaster@Honest empty state
HTML /security page onlyYou want human prose plus a formAssuming parsers will scrape the HTMLUseful extra, not RFC 9116

When a public HTML contact page still wins

A human /security page still wins for policy prose and a form people can understand. The well-known file still wins for parsers. An expired file with a dead Contact wins nothing. Missing security.txt is not a roast F; a decorative stale file is a process miss.

Common mistakes

The first mistake is shipping Contact to a mailbox nobody monitors.

The second mistake is letting Expires lapse while leaving the file up as if it were current.

The third mistake is treating a missing security.txt as a RoastMyOpsec F.

What a URL roast can prove

RoastMyOpsec does not require security.txt and does not score Expires, Contact, JSON-LD, or Open Graph as standalone Fs. The free roast is headers, TLS, cookies, bounded paths (.git/HEAD, .env, package.json signatures), and js-secrets on a consented URL. If you publish RFC 9116, keep Expires honest and Contact staffed; confirm the file yourself.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Is Expires required in security.txt?
Yes. RFC 9116 requires Expires so consumers can tell whether the file is still intended to be current.
Is a missing security.txt a vulnerability?
No. It is a missed intake channel if you wanted one. It is not a roast F.
Can humans.txt hold the security mailbox instead?
You can mention people there, but parsers look at /.well-known/security.txt. Put Contact in the RFC 9116 file.

Sources

Related guides