Type something to search...
What is a website security audit and how to perform one?

What is a website security audit and how to perform one?

A website security audit is a structured review of everything that affects your site's security: the software you run, who has access, how your server and application are configured, what your code does with user input, and how well you'd recover from an incident. The goal is to find weaknesses before attackers do and turn them into a prioritized list of fixes. You don't need to be a penetration tester to run a useful audit; a methodical checklist and a few free tools will uncover most of the common problems.

This guide explains what a security audit covers, how often to do one, and walks you through a practical, step-by-step audit you can run on your own site, whether it's built on WordPress or a custom stack. By the end, you'll have a repeatable process and a clear idea of when it makes sense to bring in a professional.

What Is a Website Security Audit?

A security audit is a systematic examination of your website and its surrounding infrastructure against a set of security standards or best practices. It answers three questions:

  1. What do we have? An inventory of software, services, accounts, and data.

  2. Where are we exposed? Vulnerabilities, misconfigurations, weak access controls, and gaps in monitoring.

  3. What should we fix first? A prioritized remediation plan based on risk.

Security Audit vs. Vulnerability Scan vs. Penetration Test

These terms are related but different:

  • Vulnerability scan: An automated tool checks for known issues, such as outdated software or missing headers. Fast and cheap, but shallow.
  • Security audit: A broader review combining automated scans with manual checks of configuration, access, processes, and code. It evaluates your overall security posture.
  • Penetration test: A skilled tester actively tries to exploit vulnerabilities to see how far an attacker could get. Deeper, but usually more expensive and narrower in scope.

A good audit usually includes vulnerability scanning, and may recommend a penetration test for high-risk areas.

Why Perform a Security Audit?

Regular audits help you:

  • Find outdated or vulnerable components before automated attack tools do.
  • Remove forgotten accounts, plugins, and files that quietly increase your attack surface.
  • Confirm that security settings you configured are actually still in place.
  • Meet compliance requirements for regulations or standards such as GDPR or PCI DSS.
  • Build a baseline so you can spot unexpected changes later.
  • Give clients, stakeholders, or insurers evidence that you take security seriously.

How Often Should You Audit Your Website?

There's no single right answer, but a practical rhythm for most sites is:

  • Monthly: Quick checks of updates, users, backups, and scan results.
  • Quarterly or twice a year: A full audit using the steps below.
  • After significant changes: A redesign, a new plugin with broad permissions, a hosting migration, or a new payment integration.
  • After an incident: Any compromise, suspicious activity, or staff change involving privileged access.

High-risk sites, such as e-commerce stores and sites handling health or financial data, benefit from more frequent reviews.

Before You Start: Prepare for the Audit

  1. Take a full backup: Back up files and the database, and store the copy off-site. Some audit steps involve changing settings.

  2. Use a staging site for risky tests: Active scanning and configuration changes are safer on a copy of your site.

  3. Get permission: If you don't own the site or server, get written authorization before scanning. Scanning systems you don't own can violate terms of service or laws.

  4. Set up a findings document: A simple spreadsheet with columns for the issue, location, severity, recommended fix, owner, and status keeps things organized.

Step 1: Build an Inventory

You can't secure what you don't know about. List:

  • Domains and subdomains: Including staging, development, and old marketing sites.
  • Hosting and infrastructure: Host, server OS, web server, PHP version, database version, CDN, and DNS provider.
  • Application software: CMS version, plugins, themes, and custom code.
  • Third-party services: Payment gateways, email services, analytics, chat widgets, and form providers.
  • Accounts: Admin users, hosting panel users, SFTP/SSH users, database users, registrar accounts, and API keys.
  • Data: What personal or sensitive data you collect and where it's stored.

For WordPress, WP-CLI makes the software inventory quick:

wp core version
wp plugin list --fields=name,status,version,update_version,auto_update
wp theme list --fields=name,status,version,update_version
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

Step 2: Check Software Versions and Known Vulnerabilities

Outdated software is the most common cause of compromised sites. Check:

  • CMS core: Is WordPress (or your CMS) on the latest version?
  • Plugins and themes: Are they all updated? Are any abandoned, meaning no updates in a long time or closed on WordPress.org?
  • Server software: Is PHP on a version that still receives security support? The official PHP website lists supported versions. Is the OS receiving updates?
  • Dependencies: For custom code, run your package manager's audit tool.
# JavaScript dependencies
npm audit

# PHP dependencies (Composer 2.4+)
composer audit

# Ubuntu/Debian: list packages with pending updates
sudo apt update && apt list --upgradable

For WordPress-specific vulnerability data, use tools like Wordfence, Patchstack, or WPScan, which compare your installed versions against known vulnerabilities.

Findings to record: Any outdated component, any component with a known vulnerability, and anything unused that should be removed.

Step 3: Review User Accounts and Access

Access control problems are easy to miss because they build up slowly over time.

  1. List all admin-level users: In WordPress, go to Users > All Users and filter by Administrator. Every admin should be a real, current person who needs that level of access.

  2. Apply least privilege: Downgrade users who don't need admin access to Editor, Author, or Shop Manager as appropriate.

  3. Remove stale accounts: Former employees, old contractors, and test accounts should be deleted, with their content reassigned.

  4. Check for shared accounts: Each person should have their own login so actions can be traced.

  5. Verify two-factor authentication: Confirm that all privileged accounts have it enabled, including hosting, registrar, and email accounts.

  6. Review application passwords and API keys: In WordPress, check each user's profile for Application Passwords and revoke any that aren't needed.

  7. Audit server access: Check SSH authorized keys and SFTP users.

# List users with login shells on the server
grep -vE "nologin|false" /etc/passwd

# Review authorized SSH keys for a user
cat ~/.ssh/authorized_keys

Step 4: Review Authentication and Login Security

Check how your login system handles attacks:

  • Is login rate limiting or lockout in place?
  • Is there bot protection, such as Cloudflare Turnstile or reCAPTCHA, on login and registration forms?
  • Are password requirements reasonable, and are breached passwords blocked?
  • Is XML-RPC disabled if you don't need it?
  • Do error messages avoid revealing whether a username exists?
  • Is the session timeout appropriate for your site?

Step 5: Check HTTPS and Security Headers

Test your TLS configuration with a tool like Qualys SSL Labs, and check your response headers with a tool like the Mozilla HTTP Observatory or curl:

curl -sI https://example.com/ | grep -iE "strict-transport|content-security|x-content-type|x-frame|referrer-policy|permissions-policy"

Look for:

  • Valid certificate, not expiring soon, with automatic renewal configured.
  • HTTP redirecting to HTTPS for every URL.
  • TLS 1.2 and 1.3 only; older protocols disabled.
  • Strict-Transport-Security set.
  • X-Content-Type-Options: nosniff.
  • Content-Security-Policy present (even report-only is a good start).
  • frame-ancestors in CSP, or X-Frame-Options, to prevent clickjacking.
  • Referrer-Policy set to something sensible like strict-origin-when-cross-origin.
  • No mixed content warnings in the browser console.

Step 6: Review Server and Application Configuration

Configuration mistakes often expose more than any code vulnerability.

Web Server

  • Is directory listing disabled?
  • Are sensitive files blocked, such as .env, .git, backup archives, and log files?
  • Does the server hide its version number?

Quick checks from the outside:

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/.env
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/.git/config
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-content/uploads/

You want 403 or 404 responses, not 200. For the uploads folder, a 200 with a file listing means directory browsing is enabled.

WordPress Configuration

Review wp-config.php and core settings:

  • DISALLOW_FILE_EDIT is set to true.
  • WP_DEBUG and WP_DEBUG_DISPLAY are off in production.
  • Security keys and salts are unique and not the defaults.
  • wp-config.php has restrictive permissions.
  • Settings > General > Membership has "Anyone can register" disabled unless you need it, and the New User Default Role is Subscriber.
wp config get WP_DEBUG
wp config get DISALLOW_FILE_EDIT
wp option get users_can_register
wp option get default_role

File Permissions

Check for world-writable files and directories, which should almost never exist on a web server:

find /var/www/example.com -perm -o+w -not -type l

Typical WordPress guidance is 755 for directories and 644 for files, with wp-config.php more restrictive.

PHP Settings

Check key php.ini values using php -i or a temporary info page that you delete afterwards:

expose_php = Off
display_errors = Off
log_errors = On
allow_url_include = Off
session.cookie_httponly = 1
session.cookie_secure = 1

Step 7: Scan for Malware and Unexpected Changes

Even if you think the site is clean, verify it:

  • Run a malware scan with a security plugin such as Wordfence or MalCare, or an external scanner like Sucuri SiteCheck.
  • Verify core and plugin file checksums.
  • Look for PHP files in the uploads folder, which shouldn't normally exist.
  • Look for recently modified files you can't explain.
wp core verify-checksums
wp plugin verify-checksums --all

# PHP files in uploads (should normally be empty)
find wp-content/uploads -type f -name "*.php"

# Files changed in the last 14 days
find . -type f -mtime -14 -not -path "./wp-content/cache/*" | head -100

Also check Google Search Console under Security & Manual Actions for any reported problems.

Step 8: Review Custom Code

If your site has custom themes, plugins, or application code, review it for common vulnerabilities. Focus on anything that handles user input:

  • SQL injection: Are database queries using prepared statements, such as $wpdb->prepare() or PDO with bound parameters?
  • Cross-site scripting: Is output escaped with esc_html(), esc_attr(), esc_url(), or your framework's equivalent?
  • CSRF: Do forms and AJAX actions that change data verify nonces?
  • Authorization: Do admin actions check capabilities with current_user_can()?
  • File uploads: Are file types validated and uploads stored where they can't execute?
  • Secrets: Are API keys and passwords kept out of the repository?

A quick grep can highlight areas that need a closer look. These patterns don't prove a problem exists, but they point you to code worth reviewing:

# Raw superglobals used in custom code
grep -rnE "\\\$_(GET|POST|REQUEST|COOKIE)\[" wp-content/themes/your-child-theme wp-content/plugins/your-plugin

# Direct database queries that may not be prepared
grep -rnE "\\\$wpdb->(query|get_results|get_row|get_var)\(" wp-content/plugins/your-plugin

Here's the difference between a risky and a safe query:

<?php
// Risky: user input concatenated into SQL.
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE post_author = " . $_GET['author'] );

// Safe: prepared statement with a typed placeholder.
$author  = isset( $_GET['author'] ) ? absint( $_GET['author'] ) : 0;
$results = $wpdb->get_results(
    $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_author = %d", $author )
);

For larger codebases, static analysis tools such as PHPCS with the WordPress Coding Standards (which include security sniffs) can automate part of this review.

Step 9: Check Third-Party Scripts and Integrations

Every external script runs with full access to your pages. Review:

  • Which third-party scripts load on each page, especially checkout and login pages.
  • Whether each one is still needed.
  • Whether versioned CDN files use Subresource Integrity.
  • Whether your Content Security Policy restricts script sources.
  • Which third-party services have API keys, and whether those keys have minimal permissions.

Step 10: Test Backups and Incident Readiness

A security audit isn't complete until you've confirmed you can recover:

  1. Backups exist and are recent: Check the date of the latest file and database backup.

  2. Backups are off-site: Stored somewhere separate from your hosting account.

  3. Backups actually restore: Restore one to a staging environment and confirm the site works.

  4. Monitoring is in place: Uptime monitoring, security alerts, and activity logs are configured and going to someone who reads them.

  5. There's a response plan: You know who to call, where credentials are stored, and what steps to take if the site is compromised.

Step 11: Prioritize and Fix

Once you've gathered findings, rank them. A simple approach:

  • Critical: Actively exploitable or already compromised. Fix immediately. Examples include known vulnerable plugins, malware, and exposed .env files.
  • High: Serious weaknesses. Fix within days. Examples include admin accounts without two-factor authentication and missing backups.
  • Medium: Important hardening gaps. Fix within weeks. Examples include missing security headers and overly broad user roles.
  • Low: Good-practice improvements. Schedule them.

Assign an owner and a due date to each item, and re-check once it's fixed.

Step 12: Document and Schedule the Next Audit

Write a short summary: what you checked, what you found, what you fixed, and what's still open. Keep it with your findings spreadsheet. The next audit will be much faster when you can compare against this baseline. Then put the next audit date in your calendar.

When to Hire a Professional

A self-audit catches most common problems, but consider a professional security audit or penetration test if:

  • You process payments directly or store sensitive personal data.
  • You have significant custom code or a complex application.
  • You need formal evidence for compliance, clients, or insurers.
  • You've had a security incident and need an independent assessment.

Costs vary widely depending on scope, so ask several providers for quotes and a clear statement of what's included.


FAQ: Website Security Audits

It's a structured review of your website's software, accounts, configuration, code, and recovery processes to find security weaknesses and produce a prioritized list of fixes.

A self-audit of a typical small WordPress site might take a few hours to a day. Larger sites with custom code, multiple environments, or compliance requirements can take much longer.

Yes. Using a checklist, free scanning tools, and WP-CLI, you can find most common issues yourself. For high-risk or complex sites, a professional audit adds depth and independence.

No. A vulnerability scan is an automated check for known issues. An audit is broader and includes manual review of access, configuration, code, and processes, often using scans as one input.

A full audit once or twice a year, with lighter monthly checks, works well for most sites. Also audit after major changes or any security incident.

Only scan sites and servers you own or have written permission to test. Scanning other people's systems without authorization can break terms of service and laws.

Start with critical issues that are actively exploitable, such as known vulnerable plugins, malware, or exposed secrets. Then address high-risk access problems like missing two-factor authentication.


Conclusion

A website security audit turns security from a vague worry into a concrete, prioritized list of work. By inventorying your software and accounts, checking for known vulnerabilities, reviewing access and configuration, scanning for malware, examining custom code, and testing your backups, you'll uncover the weaknesses attackers are most likely to exploit.

The real value comes from repetition. Keep your findings document, fix issues in order of risk, and schedule the next audit before you forget. Each round gets faster, and over time your site becomes a much harder target than the many sites that never take a close look at their own defenses.

Tags :
Share :

Related Posts

What are the best WordPress security plugins?

What are the best WordPress security plugins?

The best WordPress security plugins for most sites are Wordfence, Sucuri Security, Solid Security, MalCare, All-In-One Security (AIOS), Patchstack, a

Dive Deeper
What are the most common website security threats?

What are the most common website security threats?

The most common website security threats are vulnerable or outdated software, weak and stolen passwords, malware infections, injection attacks like S

Dive Deeper
How does GDPR affect website security?

How does GDPR affect website security?

GDPR affects website security by turning it from a good habit into a legal obligation. If your website collects personal data from people in the EU (

Dive Deeper