Security guide

How to build a secure small business website.

The process behind this site, in twelve steps. It assumes a small site with a few pages and a contact form. Last reviewed October 2026.

This is general guidance, not a guarantee and not a review of your environment. Where a step names a setting, the exact menu varies by provider.

Step 1Choose the simplest architecture

A static site (plain HTML, CSS, and a little JavaScript) has no database, no login page, and no plugins to patch. That removes the most common ways small business sites get compromised. A content management system such as WordPress is reasonable when several non-technical people must edit pages, but it brings a patching duty, plugin and theme review, and an admin login that needs multi-factor authentication.

Rule of thumb: every component you add is something you must keep patched and decide to trust. Add only what the site needs.

Step 2Secure the accounts that control the site

Most website takeovers start with an account, not with the page code. Check three places.

  • Domain registrar. Enable multi-factor authentication, turn on registrar lock, enable auto-renew, and use a shared business mailbox as the account contact so recovery does not depend on one person.
  • DNS. Keep only the records you use. Delete old records that point to services you have cancelled, since an abandoned target can sometimes be claimed by someone else. Add a CAA record naming the certificate authority you use.
  • Hosting. Enable multi-factor authentication, use a unique password from a password manager, connect by SFTP or SSH and never plain FTP, give each person their own login, and remove access for former staff and contractors.

Step 3Authenticate your domain's email

Forged email from your domain damages trust and is a common route into your clients. Publish one SPF record, turn on DKIM signing with every service that sends as you, and publish a DMARC record. Start DMARC at a monitoring policy (p=none) with reporting, review who is sending as you, fix legitimate senders, then move to quarantine and finally reject. Form notifications from your site depend on this too.

Step 4Limit outside dependencies

Every third-party script, font, widget, or analytics tag can read what is on the page and widens what you must trust. Host fonts, images, and scripts yourself. Skip chat widgets and trackers unless they earn their place. Avoid inline scripts and inline styles so your Content Security Policy can be strict. If you must load a file from a CDN, pin an exact version and use Subresource Integrity. This site loads no third-party scripts and serves its own fonts.

Step 5Treat forms as a security feature

  • Use a reputable form service or a server-side handler that validates input. Do not write a mail script that passes raw input into email headers.
  • Validate on the receiving side. Browser checks can be bypassed.
  • Add a hidden honeypot field and the provider's spam filtering. Add a CAPTCHA only if abuse appears.
  • Collect the minimum. Never ask for passwords, government ID numbers, or health details in a web form.
  • Set the form method to POST so entries never appear in a URL if JavaScript fails.
  • Say in your privacy policy where submissions go.
  • When you replace a site, deactivate the old form endpoint. Its address is visible in the old page source.

Step 6Turn on HTTPS everywhere

Issue a certificate (most hosts offer a free automatic one), redirect every HTTP request to HTTPS, and fix any mixed content. Then add HTTP Strict Transport Security (HSTS), which tells browsers to use HTTPS only. Start with a short lifetime. This site ships one day, then raises to one year after a week without problems. Add the includeSubDomains and preload options only after confirming every subdomain supports HTTPS, because they are hard to undo.

Step 7Send security headers

Headers are instructions your server sends so the browser enforces limits. This is the set this site ships, in Apache .htaccess syntax. Other hosts use different syntax for the same headers.

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=86400"
Header always set Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src https://formspree.io; form-action 'self'; base-uri 'none'; frame-ancestors 'none'; upgrade-insecure-requests"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()"
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Resource-Policy "same-origin"
</IfModule>
  • Strict-Transport-Security forces HTTPS.
  • Content-Security-Policy lists where the page may load files from and send data to. If an attacker injects a script, the browser refuses to run it. Here the page may use only its own files, plus formspree.io for form posts.
  • X-Content-Type-Options stops browsers from guessing file types.
  • X-Frame-Options and the frame-ancestors setting stop other sites from framing yours, which blocks clickjacking.
  • Referrer-Policy limits how much of your address is shared with other sites.
  • Permissions-Policy switches off browser features the site does not use.
  • Cross-Origin-Opener-Policy and Cross-Origin-Resource-Policy isolate your pages and files from other origins.

A policy that is too strict breaks pages without a visible error. Test in staging and read the browser console for blocked resources before going live.

Step 8Lock down the server

  • Turn off directory listing.
  • Deny hidden files and file types that should never be public: backups, archives, logs, and database dumps. This site's .htaccess does this.
  • Use restrictive permissions. On typical shared hosting that means 644 for files and 755 for folders. Check your host's guidance.
  • Keep nothing sensitive in the web root: no site backups, exports, zip files, test pages, or configuration files.
  • Remove default and sample content, and hide the server version where your host allows.

Step 9Publish the trust files

Publish a security.txt file at /.well-known/security.txt so researchers know how to report a problem. It needs a contact and an expiry date, and the standard recommends an expiry less than a year out. Put a reminder on the calendar to renew it, because a stale file can be worse than none. Add robots.txt and sitemap.xml, and a privacy policy that matches your real data flows.

Step 10Stage, test, and cut over

  1. Upload the site to a staging subdomain. Password-protect the folder (cPanel hosts call this Directory Privacy) and send a noindex header so search engines skip it.
  2. Click every page. Submit the forms. Open the browser console and confirm there are no blocked resources.
  3. Scan the result with the free tools in the sources below. Fix anything below your target.
  4. Copy the old site to a folder outside the web root and keep it for 30 days as your rollback.
  5. Upload to production, clear any cache, and repeat the tests.
  6. After one week without problems, raise the HSTS lifetime to one year.

Step 11Maintain it

  • Monthly: confirm the certificate is renewing and the site loads. If you run a CMS, apply updates as soon as fixes are released.
  • Quarterly: rescan the headers, review who has access to the registrar, DNS, hosting, and form service, and remove anyone who no longer needs it.
  • Annually: test restoring from backup, renew security.txt, and review every third-party service the site uses.
  • Always: keep a one-page runbook with who to call, where the backups are, and how to restore the site.

Step 12Keep evidence

Insurers, auditors, and clients ask for proof. Save dated screenshots or exports showing multi-factor authentication on the registrar, DNS, and hosting accounts, your DMARC policy, your header scan results, a backup restore test, and your access review. The work then answers the questionnaire as well as protecting the site.

Want this checked on your site?

Start with the five-question readiness score, or book a conversation.

Sources and tools

  • Security.txt standard (RFC 9116): https://www.rfc-editor.org/rfc/rfc9116
  • MDN HTTP Observatory, a free header scan: https://developer.mozilla.org/en-US/observatory
  • Security Headers scanner: https://securityheaders.com
  • Qualys SSL Labs server test: https://www.ssllabs.com/ssltest/
  • OWASP Secure Headers Project: https://owasp.org/www-project-secure-headers-project/
  • MDN Content Security Policy guide: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP