You’ve found a bug in someone else’s website. Nothing dramatic — an exposed admin endpoint, a leaking API, a subdomain someone forgot to decommission. You have no obligation to tell them. But you’re the kind of person who wants to, so you try. And then you discover that reporting a vulnerability to an organization that hasn’t planned for it is one of the most demoralizing errands on the internet.
The contact page has a sales form. Support wants your order number. The generic info@ inbox never replies, or replies with a ticket number and silence. LinkedIn-messaging a security engineer feels unhinged, and half the time the message you’d send — “hi, I think I can read your customers’ data” — trips exactly the alarms that get you accused of being the attacker. People have been threatened with lawsuits for less. So a lot of the time you give up, and the bug stays open, and everyone is worse off because there was no front door.
security.txt is the fix for the front door. It’s a beautifully small idea, and four years after it became an RFC, almost nobody has one.
The whole standard fits on a napkin
RFC 9116, published in April 2022 by Ed Foudil and Yakov Shafranovich, standardizes a plain-text file you put at a fixed, predictable location: /.well-known/security.txt. A researcher — or a bot — who wants to report something checks that one path and finds out where to send it. That’s the entire concept. No API, no account, no negotiation. A well-known address for “here’s how to tell us we’re broken.”
The file is a list of fields, and the RFC makes exactly two of them mandatory:
Contact: mailto:security@example.com
Expires: 2027-01-01T00:00:00.000Z
Contact is the point of the whole exercise: an email, a phone number, or a URL to a form where reports go. Everything else is optional — Encryption (a link to your PGP key), Policy (your disclosure rules), Acknowledgments (your hall of fame), Preferred-Languages, Canonical (where the file officially lives). The RFC even says you should sign the file with OpenPGP so nobody can tamper with the contact address and quietly redirect reports to themselves. It’s a well-designed little standard. It anticipated the obvious attacks. It asks for almost nothing.
And still: when the reporting service URIports scanned the top million domains, it found a security.txt on 0.7% of them in April 2024 and on 1.25% in January 2025. Round it however you like — the standard that costs one text file and ten minutes has been ignored by 98-plus percent of the most visited sites on earth, four years in.
The Expires field is where it gets funny
Here’s the detail that turns “underused” into something more damning. RFC 9116 made Expires mandatory, and it did so deliberately: a security contact that’s silently gone stale is a trap. The person listed left the company two years ago; the inbox is unmonitored; the PGP key is lost. So the RFC forces every file to carry an expiration date and recommends you set it less than a year out, so a living file has to be renewed — a small, recurring act that proves someone is still minding it.
You can already see the problem. The one field that requires ongoing attention is the one that reveals whether anyone is paying it. And when someone actually audits the files that exist, it shows. In URIports’ January 2025 scan, 45% of the files had no Expires field at all and 13% carried a date already in the past. The site published a security.txt once, in a burst of diligence, and then did exactly what the Expires field was designed to catch: forgot about it. Only 44% of the files in that scan were fully RFC-compliant, and a missing or stale Expires is one of the most common reasons.
An expired security.txt is worse than no security.txt. A missing file is honest: it tells the researcher “there’s no formal channel here, improvise.” An expired file lies. It presents a contact address with the confident air of a maintained process, the researcher sends their careful writeup to security@, and it lands in a mailbox nobody has opened since the intern who set it up moved on. The report was made. It just wasn’t received. And the researcher, having done everything right, has no way to know the difference.
The file is a proxy for a process, and you can’t fake a process
This is the part I actually want to argue, because “adoption is low, try harder” is a boring conclusion and also wrong.
security.txt is trivial to deploy. That it hasn’t been deployed is therefore not a technical problem, and it’s not really a laziness problem either. Publishing the file is easy; meaning it is not. To publish a security.txt honestly, an organization has to have already answered the hard questions behind it: Who reads inbound vulnerability reports? What do we do when one arrives at 6pm on a Friday claiming we’re leaking data? Will we thank the reporter or threaten them? Do we have anyone who can triage a security claim, or will it sit in a support queue behind password resets? Is there a name attached to security@, or is it a black hole with good branding?
The file is the last five minutes of that work. The organizations that don’t have one, mostly, are not the ones who ran out of time before minute five. They’re the ones who never did minutes one through fifty-five — who have no process to receive a report, and so have nothing true to write in the Contact field. security.txt didn’t fail to get adopted. It succeeded at measuring something uncomfortable: most organizations have no functioning way to hear that they’re broken, and a mandatory text file can’t manufacture one. You cannot paper over a missing human with a well-known URI.
The stale files make the same point from the other direction. An expired security.txt is the fossil of a process that existed for exactly one afternoon. Someone cared enough to publish it and not enough to renew it, which is to say the intent was real and the process never was. The Expires field, almost by accident, turned into the best available public sensor for whether an organization’s security-contact process is alive or embalmed.
What it’s actually good for
I don’t want to end on “the standard is doomed,” because it isn’t, and there’s a use for it that survives the cynicism.
Even at one percent adoption, security.txt is worth publishing if you’re going to mean it — not because it will flood you with brilliant bug reports, but because the alternative is the maze I opened with, and the maze loses you the one honest reporter who would have quietly saved you. Set the file, put a real monitored address in Contact, and — this is the whole discipline — put a calendar reminder on the Expires date. The reminder is the actual product. The text file is just its receipt.
And there’s a reconnaissance angle that’s too good to leave unsaid. Because the file lives at a fixed, public path, its presence, its contents, and crucially its freshness are all observable from outside, at scale, without touching anything you shouldn’t. Whether an organization has a security.txt, and whether its Expires date is in the past, is a small but real signal about whether anyone is home in their security function — the kind of external, cross-checkable tell that good recon is built from. The standard nobody reads turns out to be quite readable, if you’re the one doing the reading. It’s just that most of what it tells you is: nobody’s here.