Website security, part 3: security headers and CSP
In the previous part, I shared how I secured the domain name: DNSSEC, records against spoofed email, CAA, Bot Fight Mode, and the www redirect. Now the focus shifts from the domain catalog to the conversation between the server and the visitor’s browser.
What I wanted to solve
On October 3, 2026, my personal website went live at rodrigoesporto.com. The secure lock was already working and the web address was protected. However, a modern website does not just return plain text. It delivers technical instructions directly to the software you use to browse the web, whether on a phone or a laptop.
If you do not specify these instructions clearly, the browser falls back on default behaviors that are often too permissive. An unprotected site can be embedded inside another page without permission, or accept external code that nobody asked for. I wanted my site to tell the browser exactly what is allowed and what is forbidden, closing doors to common abuses without added cost and without altering what the reader sees on the page.
I work during the day, and at night and on Sundays I build with AI agents. In the Cloudflare dashboard, I configured the required settings while Darth checked from the outside. Darth is the main bot: he receives any request and routes it to the right agent.
I use Cloudflare and pay for my domain there, so I am not evaluating the service as a detached bystander. I am documenting what I set up in practice on my own website.
Quick summary
- What worked: security headers configured with a strict CSP, frame blocking, disabled camera and microphone, and A+ grades on Mozilla Observatory and securityheaders.com.
- How much it cost: zero dollars in extra expenses, since I used built-in features included with Cloudflare hosting.
- How long it took: about one evening of testing and adjustments on October 3, 2026.
First: what are security headers
When you click a link, your browser asks the server for the page. The server sends back the content you see on the screen, but right ahead of that text comes a bundle of invisible technical details. That bundle is called HTTP response headers.
Think of headers like the shipping label on a parcel. The box contains the book you bought, but the label gives instructions to the delivery driver: “fragile”, “do not flip upside down”, “hand deliver only”.
On the web, security headers work the same way. They instruct the browser: “render this text, but do not execute scripts from unknown origins” or “do not allow any unknown website to display this page inside an invisible frame”.
The shipping label analogy helps explain the concept, but it has a limit. A paper label relies on the driver choosing to read it. In modern browsers, the software enforces technical instructions automatically and strictly. If the header says to block something, the browser simply refuses to run it.
What is CSP (Content Security Policy)
CSP stands for Content Security Policy. It is a set of rules that defines an exact list of approved sources for page components like scripts, images, and fonts.
Picture an office building with security at the front desk. The guard has a printed list of people allowed upstairs. If someone whose name is not on the list tries to enter, access is denied immediately.
What a CSP actually does is declare which web addresses are trustworthy. If an attacker manages to insert a malicious snippet attempting to fetch code from a foreign server, the browser checks the CSP, sees that the source is unauthorized, and refuses to download the file.
On my site, the rule states that everything must originate from rodrigoesporto.com itself. The only external resource allowed is the visitor counter script, a configuration detail I tuned for the next step.
What is clickjacking protection (blocking hidden frames)
There is a common online scam known as clickjacking. An attacker creates a deceptive page and places another site underneath an invisible frame (technically called an iframe). You think you are clicking a harmless button on the fake page, but you are actually clicking a button on the hidden site underneath.
To cut this risk off completely, the site sends a header forbidding any other domain from loading rodrigoesporto.com inside an iframe.
Think of it like a window that can only be viewed head-on, never mounted behind a two-way mirror in someone else’s shop. If another site attempts to embed my address, the browser refuses to display the frame on the spot.
What is disabling camera, microphone, and location
Your browser has built-in features that can access your camera, microphone, and physical location sensors. Video calling apps or mapping tools need these permissions to work.
A personal blog with static articles has zero need for any of that. To prevent accidental prompts or unauthorized use by any component, I used the permissions policy header (Permissions-Policy) to turn those functions off explicitly.
The header instructs the browser: on this domain, camera, microphone, and geolocation are disabled by default. Even if a script tries to request sensor access, the browser knows the house rule is to keep everything locked down.
What is a discreet referrer policy
When you read an article and click a link pointing to another website, your browser typically tells the destination site where you came from. That information travels inside a field named “referrer”.
If the original web address contains long paths or internal details that do not need to be shared, the other site collects that information unnecessarily. A referrer policy (Referrer-Policy) lets the site control what gets passed along.
I set the rule so the browser only shares the domain name when navigating to another secure address, omitting extra path details. It is a straightforward privacy practice that keeps browsing habits more private.
Testing with Mozilla Observatory and securityheaders.com
After configuring these directives on the server, you need to test them to make sure browsers actually receive the right instructions. You should never rely solely on what you think you typed into a dashboard.
I used two well-known public testing tools:
- securityheaders.com, created by security researcher Scott Helme, which evaluates HTTP response headers and awards grades from A+ down to F.
- Mozilla Observatory, developed by the Mozilla foundation (the team behind the Firefox browser), which audits overall web security posture and provides a grade.
The site rodrigoesporto.com earned the top grade, A+, on both platforms during the security review on October 3, 2026.
These grades were not claimed by me or published by my hosting provider. They were measured from the outside by independent public testing engines. The agent responsible for running these daily checks in our team routine is Segurança: he checks every day, from the outside, whether the site remains secure, without touching anything.
What I used
- The Cloudflare dashboard to apply the HTTP response headers to the published pages.
- The rodrigoesporto.com domain, already active with an SSL certificate.
- Darth, the team’s primary bot, observing from the outside while I configured the rules.
- The Segurança agent, who handles the daily external security checks.
- Online auditing tools from Mozilla Observatory and securityheaders.com.
I did not purchase any paid plugins or separate add-on subscriptions. Everything was accomplished using capabilities already included with the hosting platform.
How it worked
If you want to apply this kind of baseline protection to your own website, here is the general sequence:
- Map out which assets your site genuinely needs to load. For a simple static site, nearly everything should come from your own origin.
- Write your content security policy rules, allowing only your domain and any essential external services.
- Add the frame protection header to stop external pages from nesting your content.
- Disable unnecessary device features such as microphone, camera, and geolocation.
- Set the referrer policy to avoid leaking full URLs to other servers.
- Save these response header rules in your web server or hosting platform.
- Open the website in a standard browser and verify that all text, styling, fonts, and images still load properly.
- Go to securityheaders.com, enter your domain, and review the score. When configured correctly, the tool displays an A+ badge in green at the top.
- Go to Mozilla Observatory and run the scan. The final report confirms an A+ grade with details on each passed test.
What went wrong or what I learned
The most useful lesson from this process is that you do not need to guess which rules to create or memorize confusing syntax.
When you run a test on securityheaders.com or Mozilla Observatory, they do not just hand you a grade. They list each header individually, explain in plain language what it does, and show you the exact values to supply.
I learned that solid web security operates quietly. It does not force readers to solve visual puzzles, it does not interrupt reading with popups, and it does not slow down page loads. The site opens instantly, and visitors never notice that their browser received a protective set of guardrails in the background.
None of these tools replace judgment. They shorten the distance between “I know what I want” and “it is live”.
Costs and limits
In terms of extra money, this setup cost zero dollars. I used built-in header settings included with my hosting setup, and the testing services are free and open to everyone on the web.
It is equally important to understand the boundaries:
- An A+ score on securityheaders.com or Mozilla Observatory shows that your server headers are properly configured. It does not mean a website is immune to every conceivable issue in the future.
- Security headers rely on modern browsers. If a visitor uses an obsolete browser that does not understand modern directives, those specific protections will simply be ignored by that software.
- These rules do not stop anyone from copying public text from your pages. Their purpose is to prevent technical abuses like script injection and clickjacking.
I use Cloudflare and pay for my domain there. The A+ grades came from independent external audits on Mozilla Observatory and securityheaders.com, not from vendor promotional claims.
What I would do differently
If I were starting over today, I would run securityheaders.com during the earliest test deployment, rather than saving it for the final review pass.
Because the scan takes only a few seconds and costs nothing, it acts as a clear checklist of what is missing. Addressing headers right away helps you understand browser behavior from the very start.
Who this is for and who it is not for
This is for anyone who runs a personal website and wants to provide a clean, secure browsing environment for readers without spending extra money or installing bloated add-ons.
This is not a substitute for enterprise security audits on complex web applications that handle private databases or payment processing. Those transactional platforms involve dozens of third-party APIs and require broader compliance assessments.
It is also not for anyone who expects AI agents to run everything unsupervised: I entered the settings in the dashboard, Darth checked from the outside, and the Segurança agent performs daily rounds without modifying files.
Closing
Configuring response headers and a content security policy shuts down common vectors for abuse while keeping the reading experience fast and simple. The site rodrigoesporto.com earned an A+ grade on both Mozilla Observatory and securityheaders.com, showing that a modest personal site can meet the same standards as major web properties.
If you have a website online, run a free scan on securityheaders.com and Mozilla Observatory to see your current grades. If you want to talk about these configurations or follow the next steps of this project, you can find me on X: @RodrigoesPorto.
In the next part, I will share how I started counting visits without using cookies.
Sources and links
- Mozilla Observatory: https://developer.mozilla.org/en-US/observatory
- Security Headers: https://securityheaders.com
- Security review by the Segurança agent, October 3, 2026