How this check works
Scanaris requests /.well-known/security.txt, the standard location from RFC 9116, and if it is not there it tries /security.txt at the root, the legacy location. It only counts the file as present if it responds 200 and contains a line starting with Contact:, the one mandatory field alongside Expires. That rules out single-page apps that return their HTML for any path. If it cannot find it, it opens an informational finding: it does not cost you any points, because not having it is not a security flaw; it is a good practice you are missing.
What it is for
When someone finds a flaw in your site (a researcher, a curious user, another company), they need to know who to tell. Without a clear channel, the usual outcome is that they do not tell you, or they publish it, or they write to the generic contact form and nobody reads it. security.txt is a plain text file at a well-known path where you say "write to me here, in this language, and this is my policy". People and tools read it, and more and more bug bounty programs and insurers take it for granted. It also protects you: it makes clear that you accept responsible reports and under which conditions.
How to create it
A minimal valid file:
Contact: mailto:security@yourdomain.com
Expires: 2027-10-01T00:00:00.000Z
Preferred-Languages: en, es
Canonical: https://yourdomain.com/.well-known/security.txt
- Contact (required): a
mailto:, a form URL or atel:. You can list several, in order of preference. The mailbox has to exist and be read. - Expires (required): an ISO 8601 date after which the file is no longer valid. The RFC recommends less than a year: set yourself a reminder to renew it.
- Preferred-Languages, Policy (URL of your disclosure policy), Encryption (your PGP key) and Acknowledgments (a thanks page) are optional.
- Canonical states the official URL of the file; useful if you sign the file with PGP so nobody can publish a fake one.
Where to put it
- Nuxt, Next.js, Vite, Astro: create
public/.well-known/security.txt; it is served as is. Make sure your.gitignoredoes not ignore folders starting with a dot. - Vercel and Netlify: the same, inside the project's public folder.
- nginx or Apache: a file at
/.well-known/security.txtin the served directory; if your application catches all routes, add an exception for/.well-known/. - WordPress: upload the file over FTP to
.well-known/at the root, or use a plugin that generates it.
Serve it as text/plain and over HTTPS. If you have many domains, each needs its own or should redirect to the canonical one.
Check it is fixed
curl -si https://yourdomain.com/.well-known/security.txt | grep -iE "^(HTTP|content-type|contact|expires)"
Expected: 200, type text/plain, a Contact: line and an Expires: line with a future date.
Frequently asked questions
Will I get more spam or "bounty hunter" emails?
Some low-quality mail will arrive; that is the price of being reachable. A simple filter and a clear policy (what counts as a valid report, whether you pay or not) cut the noise. What it saves you is the alternative: finding out on Twitter.
Can I just point to the general contact form?
You can, but a dedicated mailbox that someone checks is better. If marketing reads the general form, a vulnerability report can take weeks to reach the right person.
Why does it not affect the score?
Because it measures preparedness, not exposure. The rest of the security checks, the ones that do count, are in the security checklist before launching.