# How to secure a website: a practical checklist for owners and small teams

> How to secure a website: HTTPS with HSTS, prompt updates, MFA for admins, a WAF, tested backups, security headers, email authentication and regular scans.

- URL: https://computese.com/essential-tips-to-secure-your-website/
- Author: Duong Quan Nguyen, CEO, Computese
- Published: 2024-07-30
- Updated: 2026-09-25
- Topics: Security, Hosting

## In short
- To secure a website, close the common ways in first: HTTPS with HSTS, prompt updates, MFA and least privilege on every admin account, backups kept outside the hosting account and tested by restoring, and security headers.
- Most WordPress risk sits in plugins, not core. In vendor data from Patchstack, 91% of the 11,334 new WordPress ecosystem vulnerabilities found in 2025 were in plugins, and heavily exploited ones were attacked within a median of 5 hours.
- A web application firewall blocks known attack patterns and buys time to patch, but it does not stop logins with stolen passwords, access control flaws that look like normal traffic, or requests that reach the server directly.
- Protect the domain and email as well: MFA and transfer locks at the registrar, and SPF, DKIM and DMARC so nobody can send mail in your name.
- Then check the site from outside on a schedule: external scans, alerts that reach a person, Google Search Console's Security Issues report and a timed restore test.

To secure a website, serve it only over HTTPS with HSTS, keep the CMS, plugins and server software patched, and put multi-factor authentication and least privilege on every admin account. Add a web application firewall, keep backups outside the hosting account and test them, send security headers, protect the domain and email, and scan and monitor the site.

This checklist is for site owners and the small teams that run their sites, on WordPress, another CMS, a hosted builder or a custom application. It goes in the order that closes the most risk first, says what each control does not cover, and dates the figures that change. Developer practices such as input validation and parameterized queries are in our guide to [secure coding best practices](https://computese.com/best-practices-for-secure-coding/); this post is about running the site.

## What website security has to cover

You do not need to be a target to be attacked. Automated tools sweep the internet for known flaws, and a site gets hit because it runs a vulnerable plugin or accepts a reused password, not because of who owns it. So the work is the same for every business: remove the easy ways in, limit what a stolen account can do, and make sure you would notice, and recover, if something got through.

The [OWASP Top 10](https://owasp.org/www-project-top-ten/), the standard awareness list of the most critical web application risks, is now in its [2025 edition](https://top10.owasp.org/2025). Several of its categories are about how a site is run, not only how it is coded:

- **A01 Broken access control:** someone reaches data or functions they should not. It holds the top position, and [OWASP found some form of it in every application tested](https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/).
- **A02 Security misconfiguration,** which [explicitly includes a server that sends no security headers](https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/), or sends them with weak values.
- **A03 Software supply chain failures:** [vulnerable, unmaintained or compromised third-party components](https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/). On most sites that means plugins, themes and packages.
- **A07 Authentication failures,** including sites that allow credential stuffing (automated sign-ins with passwords leaked elsewhere) or lack effective multi-factor authentication.
- **A09 Security logging and alerting failures:** [without logs and alerts](https://top10.owasp.org/2025/A09_2025-Security_Logging_and_Alerting_Failures/), a breach is neither detected nor answered in time.

Before you start, settle who is responsible for each layer. The [Canadian Centre for Cyber Security](https://www.cyber.gc.ca/en/guidance/security-considerations-your-website-itsm60005) points out that with cloud services, who patches depends on the service model: with software as a service, the provider does.

| Where the site runs        | Who patches the platform                                             | What stays with you                                            |
| -------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------- |
| Hosted site builder (SaaS) | The provider                                                         | Admin accounts and MFA, the domain, email, third-party scripts |
| Managed CMS hosting        | The host, for the server and runtime; plugins depend on the contract | Plugins, themes, admin users, backups outside the host's own   |
| Virtual or cloud server    | You                                                                  | Everything from the operating system up                        |

## Serve every page over HTTPS, then turn on HSTS

HTTPS encrypts traffic between the browser and your server and proves the visitor reached your domain. Every page needs it, not only the login and checkout pages, because anyone who can alter one unencrypted page can send the visitor anywhere. Get a certificate for every host name you serve and automate its renewal; our guide to [renewing an SSL certificate](https://computese.com/ssl-certificate/) covers the steps, the tools and the shrinking certificate lifetimes. Then close the gaps around it:

1. **Redirect every `http://` request** to the same page on `https://` with a permanent (301) redirect, on the same host name.
2. **Fix mixed content:** images, scripts or form targets still loaded over `http://` from an HTTPS page.
3. **Send the `Strict-Transport-Security` (HSTS) header** on HTTPS responses.

[HSTS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security) tells the browser to use HTTPS for your domain from then on: it upgrades any later `http://` link before sending it, and it stops offering visitors a way to click through a certificate error. Browsers ignore the header when it arrives over plain HTTP, so it only works on HTTPS responses. Its one weakness is the first visit, before the browser has seen the header; the HSTS preload list, built into browsers, closes that gap.

Roll it out in stages. The [preload list's maintainers](https://hstspreload.org/) suggest starting with `max-age=300` (five minutes), then a week, then a month, checking for broken pages at each stage before you settle on a long value. The [OWASP Secure Headers Project](https://owasp.github.io/www-project-secure-headers/best-practices/) proposes two years:

```http
Strict-Transport-Security: max-age=63072000; includeSubDomains
```

> [!WARNING]
> `includeSubDomains` applies HSTS to every subdomain, and preloading goes further: it covers all subdomains, including internal ones that are not publicly reachable, and getting off the list is slow. Preload only when every host under the domain serves HTTPS and will keep doing so. The list requires a `max-age` of at least one year, `includeSubDomains` and the `preload` directive.

Browsers are moving the same way. In October 2025, [Google announced](https://security.googleblog.com/2025/10/https-by-default.html) that Chrome 154, due in October 2026, turns on "Always Use Secure Connections" by default, so Chrome will ask for the user's permission before the first visit to any public site without HTTPS. A site still on plain HTTP will meet many visitors with a warning before its first page loads. Search asks the same question: Google's [page experience guidance](https://developers.google.com/search/docs/appearance/page-experience) lists whether your pages are served in a secure fashion among the checks for a good page experience.

## Keep the CMS, plugins and dependencies updated

WordPress's own [hardening guide](https://developer.wordpress.org/advanced-administration/security/hardening/) warns that once a release fixes a vulnerability, the information needed to exploit it is almost certainly public, and that older versions get no security updates. The same logic applies to any CMS or library. The figures below are vendor data from Patchstack, which sells WordPress vulnerability protection, published in its [State of WordPress Security in 2026](https://patchstack.com/whitepaper/state-of-wordpress-security-in-2026/) report on the year 2025:

- **11,334 new vulnerabilities** were found in the WordPress ecosystem in 2025, 42% more than in 2024.
- **91% were in plugins** and 9% in themes. WordPress core had 6, all low priority.
- **46% had no fix** from the developer by the time they were disclosed publicly.
- For the most heavily exploited vulnerabilities, the weighted median time to the **first exploitation attempt was 5 hours**, and about half of high-impact vulnerabilities were exploited within 24 hours.
- Only four of the ten vulnerabilities attacked most in 2025 were published that year; the rest dated from 2023 and 2024, still present on the sites attackers went after.

The risk sits in everything installed around the core, so that is where the work goes:

- **Turn on automatic updates** where the platform supports them. WordPress has shipped automatic updates since version 3.7, and since 5.5 administrators can [switch on auto-updates](https://wordpress.org/documentation/article/plugins-themes-auto-updates/) plugin by plugin and theme by theme; WordPress runs them twice a day.
- **Stage the big ones.** Major versions of the CMS, page builders and shop plugins go to a staging copy first, with a way back.
- **Delete what you do not use.** A deactivated plugin is still code on the server, and WordPress's guide says to delete plugins you are not using.
- **Replace abandoned components.** With almost half of vulnerabilities disclosed before a fix existed, a plugin whose developer has gone quiet is a liability. Install plugins and themes only from trusted sources.
- **Patch the server too:** the operating system, web server and runtime (PHP, Node.js, Python). A version past its end of life gets no security fixes at all.
- **Watch dependencies in custom applications.** Packages from npm, Composer or PyPI are the supply chain OWASP's A03 is about. GitHub's [Dependabot security updates](https://docs.github.com/en/code-security/concepts/supply-chain-security/dependabot-security-updates) open pull requests that update a dependency with a known vulnerability; the rest of the developer side is in the [secure coding guide](https://computese.com/best-practices-for-secure-coding/).

When updates pile up, go by exposure and evidence. CISA's [#StopRansomware Guide](https://www.cisa.gov/stopransomware/ransomware-guide) says to prioritize internet-facing servers and known exploited vulnerabilities, and CISA's [Known Exploited Vulnerabilities (KEV) catalogue](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) is its authoritative list of vulnerabilities that have been exploited in the wild. A full patch prioritization policy, with EPSS and deadlines, is in [the future of cybersecurity](https://computese.com/the-future-of-cybersecurity/).

## Protect admin accounts with MFA and least privilege

A stolen admin password switches off most other controls: whoever holds it can install a plugin, add a user or change the payment page. OWASP's advice on [authentication failures](https://top10.owasp.org/2025/A07_2025-Authentication_Failures/) is to enforce multi-factor authentication (MFA) wherever possible, because it stops credential stuffing, brute force and the reuse of stolen passwords. Apply it to every account that can change the site, not only the CMS: the hosting panel, SFTP or SSH, the database console, the domain registrar and DNS provider, the CDN or WAF dashboard, the email platform and Google Search Console.

Choose the strongest factor people will actually use. CISA's [fact sheet on phishing-resistant MFA](https://www.cisa.gov/sites/default/files/publications/fact-sheet-implementing-phishing-resistant-mfa-508c.pdf) says any MFA is better than none, but warns that some forms fall to phishing, push bombing (flooding a user with prompts until they approve one) and SIM swapping. It calls phishing-resistant MFA the gold standard and names FIDO/WebAuthn as the only widely available form. Security keys and passkeys both use it: the FIDO Alliance [describes passkeys](https://fidoalliance.org/passkeys/) as FIDO credentials built on the FIDO2 specifications.

Passwords still matter where MFA is not offered. NIST's [SP 800-63B-4](https://pages.nist.gov/800-63-4/sp800-63b.html) (July 2025) requires passwords used on their own to be at least 15 characters (8 when the password is one factor of MFA), and tells services not to impose composition rules or periodic changes, only a change when there is evidence of compromise. A password manager makes long, unique passwords practical, and OWASP recommends encouraging them.

Then cut privileges down. Least privilege means each account gets only the access its work needs, so a stolen account does limited damage. Among WordPress's [built-in roles](https://wordpress.org/documentation/article/roles-and-capabilities/), an Administrator can use every administration feature of a site, an Editor publishes and manages everyone's posts, an Author manages only their own, and a Contributor can write but not publish. Most people who update content need Editor or less.

- **One named account per person,** never a shared login, so you can remove one person without changing everyone's password.
- **Remove former staff, agencies and freelancers** on the day their work ends.
- **Put the admin area behind an extra gate** where you can. The Canadian Centre for Cyber Security recommends isolating the administrative interface and having remote administrators connect through a VPN; an IP allowlist is a lighter version of the same idea.
- **Disable the built-in code editor.** On WordPress, `define( 'DISALLOW_FILE_EDIT', true );` in `wp-config.php` removes the dashboard's theme and plugin file editor. WordPress notes it will not stop someone uploading malicious files, but it closes one easy route from a stolen admin session to running code.

## Put a web application firewall in front, and know its limits

A [web application firewall (WAF)](https://owasp.org/www-community/Web_Application_Firewall) works as a [reverse proxy](https://computese.com/reverse-proxy/) for HTTP: it checks each request against a set of rules, mostly written for common attacks such as SQL injection and cross-site scripting, and blocks the ones that match. It comes in three forms:

| Where it runs      | How it works                                                      | Examples                                                     |
| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------ |
| At the edge        | A service in front of your host; you point your DNS records at it | The WAF of your CDN or security provider, such as Cloudflare |
| On the web server  | A module that filters requests before the application sees them   | ModSecurity or OWASP Coraza with the OWASP CRS rule set      |
| In the application | A plugin that filters requests while the CMS loads                | WordPress firewall plugins such as Wordfence and Shield      |

The [OWASP CRS](https://coreruleset.org/) rule set covers SQL injection, cross-site scripting, file inclusion, code and shell injection and scanner detection, among others. Whatever the form, rules need tuning so they do not block real visitors, and upkeep as the site changes.

A WAF's most valuable job on a small site is buying time. The Canadian Centre for Cyber Security describes it as a short-term stopgap: when a vulnerability is found, a WAF rule can block the attack until the fix is deployed. OWASP calls this [virtual patching](https://cheatsheetseries.owasp.org/cheatsheets/Virtual_Patching_Cheat_Sheet.html), and is clear that fixing the code remains the first remedy; the two run side by side. What a WAF does not stop matters just as much:

- **Valid sign-ins with stolen passwords.** A login with the right password is a normal request. MFA stops it; a WAF does not.
- **Broken access control and logic flaws.** In Patchstack's 2025 vendor data, broken access control was the most exploited class of WordPress vulnerability, and the company notes these exploits look like normal authenticated traffic, with no injection pattern for a rule to match.
- **Flaws its rules do not know.** In two 2025 penetration-testing studies, Patchstack found that common hosting defences, including in-house WAFs and Cloudflare, blocked 12% of attacks on known exploited WordPress vulnerabilities in the first and 26% of attacks in the broader second. Those are figures from a vendor that sells its own protection rules, but they make the same point: a WAF is a layer, not a patch.
- **Traffic that goes around it.** An edge WAF protects only the requests that pass through it. Anyone who finds your server's own IP address can connect to it directly. [Cloudflare's documentation](https://developers.cloudflare.com/fundamentals/security/protect-your-origin-server/) recommends accepting traffic only from its IP ranges, or using authenticated origin pulls or a tunnel, and rotating the origin IP after onboarding, because historical DNS records keep the old one.

![Requests travel from the internet through a shield to a web server. Two carrying spiked attack symbols bounce off the shield; an orange request carrying a key passes through untouched.](https://computese.com/images/blog/essential-tips-to-secure-your-website/waf.f8bfbaef41-1536.webp)

*A WAF stops what looks like an attack. A login with a stolen password looks like every other login, so it walks straight through.*

## Keep backups somewhere else, and prove them by restoring

Backups turn a breach, a failed update or ransomware into an inconvenience instead of a rebuild. CISA's #StopRansomware Guide asks for offline, encrypted backups of critical data, tested regularly for availability and integrity in a disaster recovery scenario, because many ransomware variants look for reachable backups and delete or encrypt them first. For a website, that means:

1. **Back up everything needed to rebuild:** the database, uploaded media, the code or theme, and the configuration. Encrypt the backups, since configuration files hold secrets.
2. **Keep at least one copy outside the hosting account,** under different credentials, so one stolen hosting login cannot delete the site and its backups together. CISA also suggests considering a second cloud provider, in case every account with one vendor is affected.
3. **Make one copy offline or immutable.** CISA mentions the immutable storage some cloud vendors offer, with two cautions: a misconfiguration can be costly, and it does not meet every regulation's criteria.
4. **Keep history.** An infection can go unnoticed for a while, so keep enough older versions to go back to a clean one. WordPress's hardening guide adds that a separate record of each backup's checksum, or read-only media, shows a backup has not been tampered with.
5. **Restore on a schedule.** Restore a recent backup into a separate staging environment, check that pages, sign-ins and forms work, and time it.

![A web server copies its data to a vault in a separate dashed area. An orange arrow restores that copy into a second, isolated test server, which shows a check mark.](https://computese.com/images/blog/essential-tips-to-secure-your-website/backup.39265e7eba-1536.webp)

*The copy that saves you is the one outside the hosting account, and you only know it works once you have restored it somewhere else.*

The restore test gives you two numbers: how long recovery really takes (your recovery time) and how much you would lose between backups (your recovery point). Agree both with whoever depends on the site before you need them.

> [!IMPORTANT]
> A backup you have never restored is an assumption. The first real restore should not happen on the day the site is down.

## Send security headers

Security headers are instructions your server sends with each response, telling the browser to refuse behaviour your site never needs. They cost little to add, and OWASP counts a server that sends none, or sends weak values, as security misconfiguration (A02:2025). The OWASP Secure Headers Project maintains a proposed set; these are the ones to start with, as MDN describes them:

| Header                                                                                                                                             | What it does                                                                                            | Starting value                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| [`Strict-Transport-Security`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security)                       | HTTPS only on future visits, no clicking through certificate errors                                     | `max-age=63072000; includeSubDomains` |
| [`Content-Security-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy)                           | Lists where scripts, styles, images and frames may load from, which guards against cross-site scripting | Report-only first (below)             |
| [`frame-ancestors`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/frame-ancestors) (a CSP directive) | Says which sites may embed your pages in a frame, which prevents clickjacking                           | `frame-ancestors 'self'` or `'none'`  |
| [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options)                                           | The older header for the same job, still honoured by older browsers                                     | `DENY` or `SAMEORIGIN`                |
| [`X-Content-Type-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options)                             | Makes the browser trust the declared content type, and block scripts and stylesheets with the wrong one | `nosniff`                             |
| [`Referrer-Policy`](https://owasp.github.io/www-project-secure-headers/response-headers/)                                                          | Controls how much of the page address is sent in the `Referer` header with requests                     | The OWASP proposal is `no-referrer`   |

Content Security Policy is the most powerful header and the one most likely to break something, because a CMS page often loads scripts from plugins, analytics and chat widgets. Roll it out in two steps. First send the policy as [`Content-Security-Policy-Report-Only`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy-Report-Only), which reports violations without blocking anything (it needs a `report-to` endpoint to send the reports). Fix or allow what legitimately loads, then switch to the enforcing `Content-Security-Policy` header. The OWASP proposal is a strict starting point: `default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests`.

On nginx, a baseline looks like this:

```nginx
server {
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Content-Security-Policy "frame-ancestors 'self'; object-src 'none'; base-uri 'self'" always;
}
```

`always` adds the header to error responses too. Watch the [inheritance rule](https://nginx.org/en/docs/http/ngx_http_headers_module.html): a `location` block inherits `add_header` directives from its parent only if it defines none of its own, so one `add_header` inside a `location` silently drops all the others (nginx 1.29.3 added `add_header_inherit` to change that).

Also drop what no longer helps. The Secure Headers Project [lists](https://owasp.github.io/www-project-secure-headers/response-headers/) `X-XSS-Protection`, `Expect-CT`, `Public-Key-Pins` and `Feature-Policy` as deprecated, and recommends `X-XSS-Protection: 0` if the header is still sent. It suggests removing headers that advertise your software and versions, such as `Server` and `X-Powered-By`. If the site is being rebuilt, make headers part of the launch: our [web design and development](https://computese.com/services/web-design-development/) work puts security headers and a strict Content Security Policy in the definition of done.

## Make file uploads and forms safe

Any form that accepts a file lets a stranger put something on your server. The Canadian Centre for Cyber Security's first question is whether you need uploads at all: a job application may work as well with form fields as with an attached CV. Where uploads are needed, OWASP's [File Upload Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html) sets out the controls. On a CMS, most of them are settings in the form or media plugin, not code:

- **Allow only the file types the business needs,** for example PDF and DOCX for a CV, and do not trust the file's declared type, which is trivial to fake.
- **Set a size limit.**
- **Let only authorized users upload** where the use case allows it.
- **Rename files on upload and store them outside the web root,** or on a separate storage service, so an uploaded file can never run as code on your server.
- **Scan uploads** with antivirus or a sandbox, and keep the upload plugin and its libraries up to date.

This is not theoretical: in Patchstack's vendor data, one of the ten WordPress vulnerabilities attacked most in 2025 was an unauthenticated arbitrary file upload in a page-builder add-on.

Forms without files need protection from abuse. The Cyber Centre recommends account lockouts, login delays and CAPTCHAs against brute force on sign-in, plus alerts on failed login attempts; apply the same thinking to password reset and contact forms, and collect only the fields you need. How the application should validate what forms submit is developer work, covered in the [secure coding guide](https://computese.com/best-practices-for-secure-coding/).

## Protect your domain and email

Your domain is the root of everything else: whoever controls its DNS can point your website and mail anywhere. In January 2019, [CISA described exactly that campaign](https://www.cisa.gov/news-events/directives/ed-19-01-mitigate-dns-infrastructure-tampering-closed). Attackers stole the credentials of accounts that could edit DNS and changed address, mail and name server records to redirect web and mail traffic. With control of DNS, an attacker can also obtain valid certificates, so redirected traffic can be decrypted without a single browser warning. CISA's emergency directive told US federal agencies to audit their DNS records, change DNS account passwords, add MFA and watch Certificate Transparency logs for certificates they had not requested. For any business, that becomes:

- **MFA on the registrar and DNS accounts,** with the domain registered in the business's name and a contact address someone still reads.
- **Registrar locks.** [ICANN notes](https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en) that asking your registrar for `clientTransferProhibited`, `clientDeleteProhibited` and `clientUpdateProhibited` helps prevent unauthorized transfers, deletions and updates.
- **Auto-renewal** on the domain, paid with a card that will not expire unnoticed.
- **A regular check** that DNS records point where you expect, and a Certificate Transparency monitor that alerts you to new certificates for your domain.

Email is the other half. Without authentication, anyone can send mail that claims to come from your domain. Three DNS-based standards fix that together:

- **SPF** ([RFC 7208](https://www.rfc-editor.org/rfc/rfc7208.html)) lists the servers allowed to send mail for your domain. Evaluating a record may use at most 10 DNS-querying terms (`include`, `a`, `mx` and similar); past that, the check fails with a permanent error, which is easy to hit once several mail services are added.
- **DKIM** ([RFC 6376](https://www.rfc-editor.org/rfc/rfc6376.html)) signs each message with a key whose public half is published in your DNS, so the receiver can verify which domain took responsibility for it.
- **DMARC** ties both to the address people see: a message passes only if SPF or DKIM passes for a domain aligned with the `From:` domain. Your policy tells receivers what to do with failures (`none`, `quarantine` or `reject`) and where to send aggregate reports. In May 2026, DMARC moved onto the IETF Standards Track as [RFC 9989](https://www.rfc-editor.org/rfc/rfc9989.html), which replaces the earlier informational RFC 7489.

![Two mail servers send envelopes to a receiving server that checks a record in DNS. The genuine, signed envelope goes to an inbox tray; the forged one, in orange, is turned away into a bin.](https://computese.com/images/blog/essential-tips-to-secure-your-website/email.aaf81d882e-1536.webp)

*DMARC lets the receiving server check a message against your domain's published policy, so a forged sender is turned away instead of delivered.*

RFC 9989 sets out the order for a domain owner: publish SPF, sign with DKIM, set up a mailbox for aggregate reports, publish a DMARC record with `p=none` (monitoring mode), read the reports, fix every legitimate sender that fails, then decide whether to move to enforcement.

```text
example.com.          TXT  "v=spf1 include:_spf.mail-provider.example -all"
_dmarc.example.com.   TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
```

Large mailbox providers now require this. Since February 1, 2024, [Gmail has required](https://support.google.com/mail/answer/81126) SPF or DKIM from every sender, and SPF, DKIM and DMARC (a `p=none` policy is enough) from anyone sending more than 5,000 messages a day to Gmail accounts. [Outlook.com applied the same three requirements](https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/strengthening-email-ecosystem-outlook%E2%80%99s-new-requirements-for-high%E2%80%90volume-senders/4399730) to domains sending more than 5,000 messages a day from May 5, 2025, routing non-compliant mail to Junk first. Email and domain checks (DMARC, SPF and DKIM, MTA-STS, DNSSEC and registrar lock) are part of our [security testing service](https://computese.com/services/security-testing/).

## Keep DDoS attacks away from your server

A distributed denial-of-service (DDoS) attack does not break in; it floods the site until real visitors cannot reach it. A single server cannot absorb a large flood by itself, so the protection has to sit upstream: a CDN or host with DDoS protection in front of the site, caching so most requests are answered without touching the server, and rate limits on expensive pages such as login and search. The Cyber Centre also lists slowing denial-of-service attacks among the jobs a WAF can do. The origin rule from the WAF section applies here too: if the server accepts traffic from anywhere, attackers who find its address skip the protection entirely. How the attacks work, and how DDoS protection absorbs them, is in our explainer on [DDoS attacks](https://computese.com/understanding-ddos-attacks-how-they-work/).

## Monitor, log and scan your own site

Prevention sometimes fails; what matters then is how soon you know. OWASP's A09:2025 puts it plainly: without logging and monitoring, attacks and breaches cannot be detected, and without alerting it is very hard to respond quickly. Watch these, and send the alerts to a named person, not a shared inbox nobody reads:

- uptime and key pages, checked from outside your hosting
- certificate and domain expiry dates
- admin sign-ins, failed sign-ins, new admin users and newly installed plugins or themes
- changes to files that should not change, such as core files and `.htaccess`; WordPress's hardening guide recommends monitoring files for changes because attacks leave traces in the logs or on the file system
- WAF events and server error logs

Keep logs where the web server cannot rewrite them, because an intruder with access may try to clean up. OWASP asks for audit trails with integrity controls that prevent tampering or deletion.

Add the site to Google Search Console. Its [Security Issues report](https://support.google.com/webmasters/answer/9044101) lists signs that the site was hacked or could harm visitors, such as malware or phishing pages, which can carry a warning label in search results or trigger a browser warning. Google tells owners to treat the report as the source of truth. Some infections are hard to see any other way: Patchstack's report describes malware that shows clean pages to site owners and security scanners while redirecting other visitors.

Then scan your own site on a schedule and after major changes. The Canadian Centre for Cyber Security recommends building vulnerability scanning into deployment, with tools such as the open-source OWASP ZAP (Zed Attack Proxy). Free checks worth running from outside:

- **[MDN's HTTP Observatory](https://developer.mozilla.org/en-US/observatory)** assesses a site's HTTP headers and other key security settings.
- **[Qualys SSL Labs' SSL Server Test](https://www.ssllabs.com/ssltest/)** analyzes the TLS configuration in depth.
- **[ZAP](https://www.zaproxy.org/)** scans a web application for vulnerabilities; point it at staging first.

Only scan sites you own or have written permission to test. And publish a `security.txt` file ([RFC 9116](https://www.rfc-editor.org/rfc/rfc9116.html)) at `/.well-known/security.txt`, with a `Contact` line and an `Expires` date less than a year ahead, so a researcher who finds a problem knows how to tell you.

When scanning needs to be continuous and triaged rather than occasional, our [security testing service](https://computese.com/services/security-testing/) runs scheduled external scans of websites, servers and cloud accounts, triaged by engineers and closed with a re-test.

## A website security checklist to run on a schedule

Security is upkeep, not a project with an end date. This is the rhythm that keeps a small site in shape:

1. **Always on:** automatic updates, scheduled backups, and uptime, certificate and domain expiry alerts that reach a person.
2. **Every week:** confirm the automatic updates applied, stage and apply the ones that need testing, and read security alerts and WAF events.
3. **Every month:** review admin users and remove the ones nobody needs, delete unused plugins and themes, and read the DMARC aggregate reports.
4. **Every quarter:** restore a backup into staging and time it, run the header and TLS checks and an external scan, and audit DNS records and registrar settings.
5. **Every year:** review this list against the current OWASP Top 10, move the `Expires` date in `security.txt` forward, and consider a penetration test before a major launch.

If keeping up with that list is the problem, our [hosting and maintenance service](https://computese.com/services/hosting-maintenance/) covers the running side: operating system, runtime, CMS and plugin updates, backups with scheduled restore drills, uptime and certificate monitoring, and CDN, WAF, TLS and security header configuration.

## Key terms
- **OWASP Top 10**: The OWASP Foundation's awareness list of the most critical web application security risks. The current edition is the OWASP Top 10:2025.
- **HSTS**: HTTP Strict Transport Security: a response header that tells browsers to reach a domain only over HTTPS for a set time, and not to let visitors click through certificate errors.
- **Multi-factor authentication (MFA)**: Signing in with a second proof beyond the password, such as a code from an authenticator app or a security key. Phishing-resistant MFA uses the FIDO/WebAuthn standards, as security keys and passkeys do.
- **Least privilege**: Giving each account only the access its work needs, so a stolen or misused account can do limited damage.
- **Known exploited vulnerability (KEV)**: A vulnerability with evidence of exploitation in the wild. CISA's KEV catalogue lists them, and they are the first to patch.
- **Web application firewall (WAF)**: A filter in front of a website that inspects HTTP requests against rules for common attacks, such as SQL injection and cross-site scripting, and blocks the ones that match.
- **Virtual patching**: A WAF rule that blocks attempts to exploit a known vulnerability until the software itself is fixed. It buys time; it does not replace the fix.
- **Content Security Policy (CSP)**: A response header that lists where a page may load scripts, styles, frames and other resources from, which limits what injected code can do.
- **Clickjacking**: Loading your page invisibly inside another site's frame to trick visitors into clicking something on it. The CSP frame-ancestors directive prevents it.
- **SPF, DKIM and DMARC**: Email authentication standards. SPF lists the servers allowed to send for a domain, DKIM signs messages, and DMARC tells receivers what to do when neither passes for the domain in the From address.

## Common questions

### What is the most important step to secure a website?

No single step covers it, but two close the most common ways in: multi-factor authentication on every account that can change the site, and prompt updates for the CMS, plugins and server. In Patchstack's vendor data, heavily exploited WordPress flaws were attacked within a median of 5 hours of disclosure, so turn on automatic updates where you can.

### Is HTTPS enough to make a website secure?

No. HTTPS protects data on its way between the browser and the server, and proves the visitor reached your domain. It does nothing about a vulnerable plugin, a stolen password or a missing backup. It is the first item on the checklist, not the whole list, and it needs HSTS so browsers stop using plain HTTP for your domain.

### Do I need a web application firewall?

For most public sites, especially a CMS with plugins, yes: it blocks common attack patterns and can hold off a known vulnerability until you patch. It does not replace updates or MFA, because it cannot tell a stolen password from the real owner's, and it misses flaws that look like normal traffic.

### How often should I scan my website for vulnerabilities?

On a schedule and after every major change, such as a new plugin, theme or release. A quarterly external scan is a sensible minimum for a small site; sites that change often or hold customer data benefit from continuous scanning. Only scan sites you own or have written permission to test.

### How do I know if my website has been hacked?

Warning signs include admin users nobody created, new or changed files, redirects to other sites, spam pages in search results, and warnings in browsers or in Google Search Console's Security Issues report. Some malware shows clean pages to the owner while redirecting other visitors, so check from outside and read Search Console rather than trusting what you see when signed in.

### Does website security affect SEO?

Yes. Google's page experience guidance asks whether pages are served securely, and a hacked site can carry warning labels in search results or trigger browser warnings. Once every issue is fixed, you request a review from the Security Issues report in Search Console.

## Sources
1. [OWASP Top 10:2025](https://top10.owasp.org/2025), OWASP Foundation
2. [OWASP Top 10 project page](https://owasp.org/www-project-top-ten/), OWASP Foundation
3. [A01:2025 Broken Access Control](https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/), OWASP Foundation
4. [A02:2025 Security Misconfiguration](https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/), OWASP Foundation
5. [A03:2025 Software Supply Chain Failures](https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/), OWASP Foundation
6. [A07:2025 Authentication Failures](https://top10.owasp.org/2025/A07_2025-Authentication_Failures/), OWASP Foundation
7. [A09:2025 Security Logging and Alerting Failures](https://top10.owasp.org/2025/A09_2025-Security_Logging_and_Alerting_Failures/), OWASP Foundation
8. [Security considerations for your website (ITSM.60.005)](https://www.cyber.gc.ca/en/guidance/security-considerations-your-website-itsm60005), Canadian Centre for Cyber Security
9. [Strict-Transport-Security header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security), MDN Web Docs
10. [HSTS Preload List Submission](https://hstspreload.org/), Chromium project
11. [HTTPS by default](https://security.googleblog.com/2025/10/https-by-default.html), Google Security Blog
12. [State of WordPress Security in 2026](https://patchstack.com/whitepaper/state-of-wordpress-security-in-2026/), Patchstack
13. [Hardening WordPress](https://developer.wordpress.org/advanced-administration/security/hardening/), WordPress.org
14. [Plugins and themes auto-updates](https://wordpress.org/documentation/article/plugins-themes-auto-updates/), WordPress.org
15. [About Dependabot security updates](https://docs.github.com/en/code-security/concepts/supply-chain-security/dependabot-security-updates), GitHub Docs
16. [#StopRansomware Guide](https://www.cisa.gov/stopransomware/ransomware-guide), CISA
17. [Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog), CISA
18. [Implementing Phishing-Resistant MFA (fact sheet, October 2022)](https://www.cisa.gov/sites/default/files/publications/fact-sheet-implementing-phishing-resistant-mfa-508c.pdf), CISA
19. [Passkeys](https://fidoalliance.org/passkeys/), FIDO Alliance
20. [SP 800-63B-4: Digital Identity Guidelines, Authentication and Authenticator Management](https://pages.nist.gov/800-63-4/sp800-63b.html), NIST
21. [Roles and Capabilities](https://wordpress.org/documentation/article/roles-and-capabilities/), WordPress.org
22. [Web Application Firewall](https://owasp.org/www-community/Web_Application_Firewall), OWASP Foundation
23. [OWASP CRS](https://coreruleset.org/), OWASP CRS Project
24. [Virtual Patching Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Virtual_Patching_Cheat_Sheet.html), OWASP Cheat Sheet Series
25. [Protect your origin server](https://developers.cloudflare.com/fundamentals/security/protect-your-origin-server/), Cloudflare Docs
26. [Best Practices](https://owasp.github.io/www-project-secure-headers/best-practices/), OWASP Secure Headers Project
27. [Response Headers](https://owasp.github.io/www-project-secure-headers/response-headers/), OWASP Secure Headers Project
28. [Content-Security-Policy header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy), MDN Web Docs
29. [Content-Security-Policy-Report-Only header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy-Report-Only), MDN Web Docs
30. [CSP: frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/frame-ancestors), MDN Web Docs
31. [X-Frame-Options header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options), MDN Web Docs
32. [X-Content-Type-Options header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options), MDN Web Docs
33. [Module ngx_http_headers_module](https://nginx.org/en/docs/http/ngx_http_headers_module.html), nginx
34. [File Upload Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html), OWASP Cheat Sheet Series
35. [Emergency Directive 19-01: Mitigate DNS Infrastructure Tampering](https://www.cisa.gov/news-events/directives/ed-19-01-mitigate-dns-infrastructure-tampering-closed), CISA
36. [EPP Status Codes: What Do They Mean, and Why Should I Know?](https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en), ICANN
37. [RFC 7208: Sender Policy Framework (SPF)](https://www.rfc-editor.org/rfc/rfc7208.html), IETF
38. [RFC 6376: DomainKeys Identified Mail (DKIM) Signatures](https://www.rfc-editor.org/rfc/rfc6376.html), IETF
39. [RFC 9989: Domain-Based Message Authentication, Reporting, and Conformance (DMARC)](https://www.rfc-editor.org/rfc/rfc9989.html), IETF
40. [Email sender guidelines](https://support.google.com/mail/answer/81126), Google
41. [Strengthening Email Ecosystem: Outlook's New Requirements for High-Volume Senders](https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/strengthening-email-ecosystem-outlook%E2%80%99s-new-requirements-for-high%E2%80%90volume-senders/4399730), Microsoft Tech Community
42. [Security Issues report](https://support.google.com/webmasters/answer/9044101), Google Search Console Help
43. [HTTP Observatory](https://developer.mozilla.org/en-US/observatory), MDN Web Docs
44. [SSL Server Test](https://www.ssllabs.com/ssltest/), Qualys SSL Labs
45. [ZAP (Zed Attack Proxy)](https://www.zaproxy.org/), ZAP Dev Team
46. [RFC 9116: A File Format to Aid in Security Vulnerability Disclosure](https://www.rfc-editor.org/rfc/rfc9116.html), IETF
47. [Understanding page experience in Google Search results](https://developers.google.com/search/docs/appearance/page-experience), Google Search Central
