← Back to blog

Website Security Checklist for SMEs: 15 Checks to Do Right Now

Why This Checklist Exists

Most website security guides are written for developers and system administrators. They assume you know what SSH is, that you can read server configuration files, and that you have time to study web application security in depth. That is not realistic for a business owner who needs to understand their risk level and take action.

This checklist is different. Each of the 15 items includes: what it is in plain language, why it matters, how to check it yourself using free tools, and what to do if the check fails. You do not need technical skills for most of these. For the ones that require developer involvement, you will know exactly what to ask for.

We have also published a more technical website security audit checklist for developers and IT teams. This guide is the business owner version.

How to Use This Checklist

Go through each item in order. They are arranged from highest priority (items that expose you to the most immediate risk) to lower priority (items that improve your security posture but are less likely to be the vector for an immediate attack).

For each item, score yourself:

  • Pass (2 points): The check passes completely.
  • Partial (1 point): Some aspects pass, others need work.
  • Fail (0 points): The check fails entirely.

At the end, add up your score. The maximum is 30 points. Here is what your score means:

ScoreRatingWhat It Means
25-30GoodYour website has a solid security foundation. Focus on maintaining it.
18-24FairYou have some protections in place but significant gaps remain. Address the failures promptly.
10-17PoorYour website has serious security weaknesses. Prioritize remediation immediately.
0-9CriticalYour website is highly vulnerable. Stop reading and contact a security professional today.

Check 1: HTTPS Everywhere

What It Is

HTTPS encrypts the connection between your visitor's browser and your web server. Without it, everything transmitted (including form submissions, login credentials, and personal data) can be intercepted by anyone on the same network.

Why It Matters

Without HTTPS, data submitted through your contact forms travels in plain text. Someone on the same WiFi network (a coffee shop, a hotel, an airport) can read everything. Google also penalizes non-HTTPS sites in search rankings, and browsers display "Not Secure" warnings that drive visitors away.

How to Check

  1. Visit your website. Look at the address bar. Is there a padlock icon? Does the URL start with https://?
  2. Try visiting http://yoursite.com (without the 's'). Does it automatically redirect to https://yoursite.com?
  3. Check all pages, not just the homepage. Some sites have HTTPS on the homepage but HTTP on subpages.
  4. Use SSL Labs Server Test at ssllabs.com/ssltest to check your certificate and configuration. You want a grade of A or A+.

How to Fix

If HTTPS is missing: contact your hosting provider. Most offer free SSL certificates through Let's Encrypt. If HTTPS exists but HTTP does not redirect: add a server-level redirect rule. If SSL Labs gives a grade below A: your SSL/TLS configuration needs updating (your hosting provider or developer can handle this).

Check 2: CMS and Plugins Up to Date

What It Is

Your content management system (WordPress, Joomla, Drupal, etc.) and all installed plugins/extensions should be running their latest versions. Outdated software contains known vulnerabilities that attackers actively scan for.

Why It Matters

This is the single most common entry point for website compromises. When a vulnerability is disclosed in a popular plugin, automated scanning tools probe every website on the internet for that specific flaw within hours. If you are running the vulnerable version, you will be found.

How to Check

  1. Log in to your CMS admin panel.
  2. Check the CMS core version against the latest available version on the official website.
  3. Check each installed plugin/extension for available updates.
  4. For WordPress: install the WPScan plugin or use the free online scanner at wpscan.com.
  5. Check your PHP version (usually shown in the hosting control panel). It should be 8.2 or higher as of 2025.

How to Fix

Update everything. If you are afraid of breaking things, set up a staging environment first (ask your hosting provider). Remove any plugins that have not been updated by their developers in over a year. Remove any plugins you are not actively using.

Check 3: Admin Access Secured with 2FA

What It Is

Two-factor authentication (2FA) requires a second verification step beyond your password when logging in to your website's admin panel. This is typically a time-based code from an app like Google Authenticator, Authy, or a hardware key.

Why It Matters

Passwords get stolen. They get phished, they get leaked in data breaches, they get guessed. If your admin password is compromised and you do not have 2FA, the attacker has full access to your website. With 2FA, a stolen password alone is not enough.

How to Check

  1. Try logging in to your CMS admin panel. Are you asked for a second factor after entering your password?
  2. Check all admin-level accounts, not just yours. Every person with admin access should have 2FA enabled.
  3. Verify that the 2FA method is app-based (TOTP) or hardware-based, not SMS. SMS-based 2FA is better than nothing but can be bypassed through SIM swapping.

How to Fix

For WordPress: install a 2FA plugin like WP 2FA or Two Factor Authentication. For Joomla: use the built-in Two Factor Authentication feature. For other platforms: check their documentation for 2FA support. Set up 2FA for every admin account immediately.

Check 4: Security Headers Configured

What It Is

Security headers are HTTP response headers that tell browsers how to behave when loading your site. They can prevent clickjacking, block XSS attacks, control which external resources can load, and enforce HTTPS. For a detailed explanation, see our article on HTTP security headers.

Why It Matters

Without security headers, your site relies entirely on the browser's default behavior, which is permissive. Attackers can embed your site in an iframe on a malicious page (clickjacking), inject scripts that your browser will execute, or downgrade your HTTPS connection.

How to Check

  1. Visit securityheaders.com and enter your domain.
  2. Look for these headers: Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, Referrer-Policy, Permissions-Policy.
  3. A grade of A or A+ is the target. Anything below B indicates missing headers.

How to Fix

Security headers are configured at the server level or through your CMS. For WordPress, plugins like HTTP Headers can set them. For other platforms, the headers are typically added to the web server configuration (Apache .htaccess or Nginx config). Provide the securityheaders.com report to your developer and ask them to address every missing header.

Check 5: Contact Forms Protected

What It Is

Your contact forms should be protected against spam bots and injection attacks. This means CAPTCHA or equivalent bot detection, server-side input validation, rate limiting, and protection against email header injection. We have a dedicated article on why unprotected contact forms are dangerous.

Why It Matters

Unprotected contact forms can be abused for spam relay (sending spam through your mail server, potentially getting your domain blacklisted), phishing distribution, injection attacks, and server resource exhaustion. A form without any bot protection will be found and abused within days of going live.

How to Check

  1. Visit your contact form. Is there a CAPTCHA, reCAPTCHA, hCaptcha, or honeypot field?
  2. Try submitting the form with obviously fake data. Does validation catch it?
  3. Submit the form multiple times in quick succession. Is there rate limiting?
  4. Check your inbox: are you receiving spam through your contact form? If yes, it is not properly protected.

How to Fix

Add a CAPTCHA solution (Google reCAPTCHA v3 is invisible and effective). Implement server-side validation for all form fields. Add rate limiting (maximum submissions per IP per time period). Ensure the form handler sanitizes all input before using it in email headers.

Check 6: Backups Tested

What It Is

Regular, automated backups of your website files and database, stored in a separate location from your web server, and tested to confirm they can actually be restored.

Why It Matters

Backups are your last line of defense. If your site is compromised, defaced, or hit by ransomware, a clean backup is the fastest way to recover. But a backup you have never tested is a backup that might not work when you need it.

How to Check

  1. Ask your hosting provider or developer: where are backups stored? How often are they taken? How far back do they go?
  2. Request a test restore. Can they restore yesterday's backup to a temporary location and show you it works?
  3. Verify that backups include both files and the database. A file-only backup without the database is useless for a CMS site.
  4. Verify that backups are stored off-server. If backups are on the same server as your website, a server compromise destroys both.

How to Fix

Set up automated daily backups. Store them in a separate location (different server, cloud storage like AWS S3, Google Cloud Storage, or Backblaze B2). Retain at least 30 days of backups. Test a restore at least quarterly. For WordPress: plugins like UpdraftPlus or BackWPup can automate this.

Check 7: File Upload Restrictions

What It Is

If your website allows file uploads (through forms, media libraries, or user profiles), those upload handlers should restrict which file types are accepted, check file contents (not just extensions), limit file sizes, and store uploaded files outside the web root or in a location that prevents execution.

Why It Matters

Unrestricted file upload is one of the most dangerous vulnerabilities. An attacker who can upload a PHP file (or other executable script) to your server can execute arbitrary code, take full control of your website, and potentially compromise the entire server.

How to Check

  1. Identify all file upload points on your website (contact forms with attachments, media uploaders, profile picture uploads).
  2. Try uploading a file with an unusual extension (like .php, .asp, .jsp). It should be rejected.
  3. Try uploading an oversized file. There should be a size limit.
  4. Ask your developer: are uploaded files stored in a directory that prevents script execution?

How to Fix

Implement a whitelist of allowed file types (e.g., only .jpg, .png, .pdf, .docx). Validate file content, not just the extension. Set reasonable file size limits. Store uploads outside the web root or configure the upload directory to prevent script execution. Rename uploaded files to prevent path traversal attacks.

Check 8: Error Messages Don't Leak Information

What It Is

When something goes wrong on your website (a page not found, a form error, a server issue), the error message shown to visitors should be generic and helpful, not technical and revealing. Detailed error messages can expose your technology stack, file paths, database structure, and internal logic to attackers.

Why It Matters

An error message that shows a PHP stack trace, a SQL query, a file path like /var/www/html/wp-content/..., or a database table name gives an attacker information about your system that helps them plan a more targeted attack. It is free reconnaissance.

How to Check

  1. Visit a page that does not exist on your site (e.g., yoursite.com/thispagecannotexist123). What do you see? A custom 404 page is good. A raw server error is bad.
  2. If you have a search function, try searching for special characters like ' or ;. Do you see database error messages?
  3. Try adding ?debug=true or ?error=1 to your URL. Any change in output?
  4. Check if WP_DEBUG is set to false in your WordPress configuration (ask your developer).

How to Fix

Disable debug mode in production. Configure custom error pages for 404, 403, 500, and other HTTP error codes. Ensure error logging goes to server log files, not to the screen. Review your CMS configuration for any debug or verbose error settings that should be off in production.

Check 9: Directory Listing Disabled

What It Is

Directory listing is a web server feature that, when enabled, shows the contents of a directory when there is no index file (like index.html or index.php). If someone navigates to yoursite.com/uploads/ and directory listing is on, they see a list of every file in that directory.

Why It Matters

Directory listing can expose backup files, configuration files, uploaded documents, and other files that should not be publicly accessible. Attackers specifically scan for open directories as part of their reconnaissance.

How to Check

  1. Try visiting common directories on your site: yoursite.com/wp-content/uploads/, yoursite.com/images/, yoursite.com/assets/, yoursite.com/backup/.
  2. If you see a list of files and folders, directory listing is enabled and needs to be turned off.
  3. If you see a 403 Forbidden error or are redirected, directory listing is properly disabled.

How to Fix

For Apache: add Options -Indexes to your .htaccess file. For Nginx: ensure autoindex off; is set (this is the default, but verify). For other servers: check the documentation for the directory listing directive and ensure it is disabled.

Check 10: Default Credentials Changed

What It Is

Every default username, password, and configuration setting that came with your CMS, hosting panel, database, or any other system component should have been changed from the defaults during setup.

Why It Matters

Default credentials are the first thing automated attack tools try. If your WordPress admin username is "admin," bots are already attempting to brute-force that account. Default database passwords, default hosting panel credentials, and default API keys are all well-known and actively targeted.

How to Check

  1. Is your CMS admin username "admin," "administrator," or the name of your CMS? Change it.
  2. Can you log in to your hosting control panel with credentials you did not specifically choose? Change them.
  3. Are there any test accounts, demo accounts, or setup accounts still active? Remove them.
  4. Check for default database prefixes (WordPress uses wp_ by default). While not a credential, changing it adds a layer against automated SQL injection attempts.

How to Fix

Change every default credential. Use a password manager to generate and store strong, unique passwords. Remove any accounts that are not actively needed. If your CMS does not allow renaming the admin username directly, create a new admin account with a unique name and delete the default one.

Check 11: XML-RPC Disabled (WordPress)

What It Is

XML-RPC is a remote communication protocol in WordPress that allows external applications to interact with your site. It was useful before the REST API existed but is now largely unnecessary and is a common attack vector for brute force and DDoS amplification attacks.

Why It Matters

XML-RPC allows attackers to attempt hundreds of password combinations in a single request (through the system.multicall method), bypassing most brute force protections. It is also used in DDoS amplification attacks (pingback abuse). Unless you specifically need XML-RPC for a connected application, it should be disabled.

How to Check

  1. Visit yoursite.com/xmlrpc.php. If you see "XML-RPC server accepts POST requests only," it is enabled.
  2. If you get a 403 Forbidden or 404 Not Found, it is disabled or blocked.

How to Fix

For WordPress: add a plugin like Disable XML-RPC or add the following to your .htaccess file to block access. Alternatively, your security plugin (if you have one) likely has an option to disable it. If you use Jetpack or the WordPress mobile app, you may need XML-RPC; consult with your developer.

Check 12: User Enumeration Blocked

What It Is

User enumeration is a technique where an attacker discovers valid usernames on your website. In WordPress, this is trivially easy: visiting yoursite.com/?author=1 reveals the username of the first admin account. The REST API endpoint /wp-json/wp/v2/users can also expose usernames.

Why It Matters

Knowing a valid username is half the battle for a brute force attack. If the attacker knows the username is "marco" instead of having to guess both username and password, the attack becomes orders of magnitude more efficient.

How to Check

  1. Visit yoursite.com/?author=1. If it redirects to a URL containing a username (like /author/marco/), user enumeration is possible.
  2. Visit yoursite.com/wp-json/wp/v2/users. If it returns a JSON list of users with their usernames, the REST API is exposing user data.
  3. Try entering a valid username with a wrong password on the login page. Does the error message say "incorrect password" (revealing that the username exists) or a generic "incorrect credentials"?

How to Fix

Block author archive enumeration by adding a redirect rule or using a security plugin. Restrict the REST API users endpoint to authenticated requests only. Configure your login page to show generic error messages that do not confirm whether a username exists.

Check 13: Third-Party Scripts Audited

What It Is

Most websites load JavaScript from third-party sources: Google Analytics, Facebook Pixel, chat widgets, advertising networks, font services, CDN-hosted libraries. Each of these is code running on your website that you do not control.

Why It Matters

If any third-party script is compromised, the attacker's code runs on your website with the same privileges as your own code. This has happened repeatedly: the Magecart attacks compromised third-party scripts on e-commerce sites to steal credit card numbers. A compromised analytics script can keylog every visitor. You are trusting every third-party script provider with your visitors' security.

How to Check

  1. Open your website in Chrome or Firefox. Press F12 to open Developer Tools. Go to the "Sources" or "Network" tab.
  2. List every domain that scripts are loaded from. How many are there? Do you recognize all of them?
  3. For each third-party script, ask: do we actually use this? Is it still needed? What data does it have access to?
  4. Check if you are loading any scripts from CDNs with Subresource Integrity (SRI) hashes. Without SRI, a compromised CDN can serve malicious code.

How to Fix

Remove every third-party script you do not actively need. Implement Subresource Integrity for any CDN-hosted scripts. Use Content Security Policy to restrict which domains can serve JavaScript on your pages. Audit your third-party scripts at least annually. Consider self-hosting critical scripts (like analytics) instead of loading them from third-party servers.

Check 14: Cookie Consent Compliant

What It Is

If your website uses cookies (and it almost certainly does if you run analytics, use a CMS with login, or have any third-party integrations), you need a cookie consent mechanism that complies with applicable regulations (Swiss DSG, EU GDPR, ePrivacy Directive).

Why It Matters

This is a compliance and legal issue more than a technical security issue, but it overlaps with security. Cookie consent banners that do not actually block cookies until consent is given (which is extremely common) create legal liability. Additionally, cookie management is part of your overall data governance posture.

How to Check

  1. Visit your website in a private/incognito browser window. Do you see a cookie consent banner?
  2. Before accepting cookies, check if analytics scripts are already running (Developer Tools > Network tab, filter by the analytics domain). They should not load until consent is given.
  3. Click "Reject" or "Necessary only" on the consent banner. Do non-essential cookies get set anyway? (Check Developer Tools > Application > Cookies.)
  4. Is there a way for visitors to change their cookie preferences after initial consent?

How to Fix

Implement a proper consent management platform (CMP) that actually blocks non-essential cookies and scripts until consent is given. Free options include Cookiebot (for small sites), Osano, or open-source solutions like Klaro. The banner should offer meaningful choices (accept all, reject all, customize) and respect the visitor's selection.

Check 15: Incident Response Plan Exists

What It Is

An incident response plan is a documented set of steps to follow when (not if) your website is compromised. It covers who to contact, what to do first, how to contain the damage, how to restore service, and how to investigate what happened.

Why It Matters

When your website gets hacked, the worst time to figure out what to do is while it is happening. Panic leads to mistakes: wiping evidence before investigation, restoring without patching the vulnerability (leading to re-compromise), failing to notify affected parties within regulatory timeframes, or simply not knowing who to call.

How to Check

  1. Does your organization have a written document that describes what to do if the website is compromised?
  2. Does it include contact information for: your hosting provider's emergency support, your web developer or agency, a security incident response team (even if external)?
  3. Does it describe the steps: isolate (take the site offline), preserve (do not delete evidence), investigate, restore from backup, patch, monitor, notify?
  4. Has anyone on your team actually read it?
  5. Under Swiss law (nDSG), do you know your obligations for notifying the FDPIC and affected individuals in case of a data breach?

How to Fix

Create a simple one-page incident response plan. It does not need to be elaborate. Minimum contents:

  1. Detection: How will you know if the site is compromised? (Monitoring, customer reports, Google alerts.)
  2. Contacts: Phone numbers and email addresses for hosting provider, developer, security team, legal counsel.
  3. Immediate actions: Take the site offline. Do not delete anything. Contact your security team.
  4. Investigation: Determine what happened, when, and what data was affected.
  5. Restoration: Restore from a clean backup. Apply the security patch that closes the vulnerability.
  6. Notification: If personal data was compromised, notify the FDPIC within 72 hours and notify affected individuals.
  7. Post-incident: Document what happened. Update defenses. Review and update this plan.

Your Score

Add up your points from all 15 checks. Here is a quick reference:

CheckPoints
1. HTTPS Everywhere__ / 2
2. CMS and Plugins Up to Date__ / 2
3. Admin Access with 2FA__ / 2
4. Security Headers__ / 2
5. Contact Forms Protected__ / 2
6. Backups Tested__ / 2
7. File Upload Restrictions__ / 2
8. Error Messages Safe__ / 2
9. Directory Listing Disabled__ / 2
10. Default Credentials Changed__ / 2
11. XML-RPC Disabled__ / 2
12. User Enumeration Blocked__ / 2
13. Third-Party Scripts Audited__ / 2
14. Cookie Consent Compliant__ / 2
15. Incident Response Plan__ / 2
Total__ / 30

What to Do with Your Results

If you scored 25 or above, well done. Focus on maintaining your security posture with regular reviews (quarterly is a good cadence).

If you scored between 18 and 24, you have work to do but you are not in immediate danger. Address the failed checks within the next 30 days, starting with checks 1-6 (the highest priority items).

If you scored below 18, your website has significant security gaps that could be exploited at any time. The items in checks 1-3 (HTTPS, updates, and 2FA) should be addressed this week. Everything else within the next 30 days.

If you scored below 10, you need professional help. The number of open vulnerabilities means that your site is likely already being probed by automated tools, if not already compromised. Contact a security professional immediately.

Making This a Recurring Practice

Security is not a one-time activity. Run through this checklist every quarter. Assign someone in your organization as the person responsible for the quarterly review. Log the results so you can track improvement over time.

Every time you add new functionality to your website (a new form, a new plugin, a new integration), re-run the relevant checks. New features mean new attack surface.

If you need help running these checks, interpreting the results, or fixing the issues found, get in touch with us. We work with SMEs across Ticino and Switzerland to make website security practical, affordable, and effective.

Want to know if your site is secure?

Request a free security audit. In 48 hours you get a complete report.

Request Free Audit

Quick Contact