Skip to main content
Back to blog
March 29, 2026·Updated May 2, 2026|12 min read|Antoine Duno|Web Security

How to Run a Website Security Audit: Step-by-Step Process

A website security audit does not need to be expensive or time-consuming if you follow a structured process. This step-by-step guide walks through everything from scope definition to remediation tracking, with the right tools for each phase.

Antoine Duno

1,720 words

AD

Antoine Duno

Founder of ZeriFlow · 10 years fullstack engineering · About the author

Key Takeaways

  • A website security audit does not need to be expensive or time-consuming if you follow a structured process. This step-by-step guide walks through everything from scope definition to remediation tracking, with the right tools for each phase.
  • Includes copy-paste code examples and step-by-step instructions.
  • Free automated scan available to verify your implementation.

How to Run a Website Security Audit: Step-by-Step Process

A website security audit is a structured process for identifying vulnerabilities in a web application before attackers do. For most development teams, audits happen reactively — after an incident, or when a customer asks for a security questionnaire.

The better approach is a repeatable, scheduled audit process that you run every quarter. This guide gives you exactly that: a 7-step process with specific tools for each phase, designed for developers and small teams who do not have a dedicated security team.


Who Should Run This Audit

This process is designed for: - Developers doing a pre-launch security review of a new application - SaaS founders preparing for SOC 2 or enterprise customer security reviews - Engineering teams adding a quarterly security review to their process - Anyone who has just been asked "do you have a security audit?"

It is not a penetration test. It will not find every vulnerability. What it will find is the entire class of common, exploitable, and often embarrassing vulnerabilities that comprise the majority of real-world web application compromises.


Step 1: Define Scope

Before running any tools, define what you are auditing. This prevents scope creep, focuses your effort, and creates a document trail.

Scope definition checklist

  • Domains and subdomains: List every domain and subdomain in scope (yourdomain.com, app.yourdomain.com, api.yourdomain.com, admin.yourdomain.com)
  • Authentication states: Unauthenticated, authenticated as a regular user, authenticated as an admin
  • Excluded systems: Third-party services you do not control (Stripe, Auth0, Cloudflare) — note them as out of scope but document that they are used
  • Data classification: Identify which parts of the application handle PII, payment data, or credentials
  • Test environment: Prefer running tests against a staging environment, especially for active testing

Write this down. A one-page scope document is enough and becomes part of your audit report.


Step 2: Automated Scanning

Automated scanning is the most efficient way to surface common vulnerabilities. Run it first — it establishes your baseline and often finds 10–15 issues before you have looked at a single line of code.

Surface-level scan (infrastructure and headers)

Run a free scan at ZeriFlow. In 60 seconds you get: - TLS/HTTPS configuration grade - All HTTP security headers checked (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, COOP, X-Content-Type-Options) - Cookie security flags for every cookie - DNS security configuration - Email authentication (SPF, DKIM, DMARC) - A /100 security score with prioritized findings

This single scan covers the entire infrastructure and transport layer and gives you a prioritized list of fixes.

DAST (Dynamic Application Security Testing)

For a deeper automated scan that tests the running application, use:

  • OWASP ZAP (free) — automated scanner that crawls your site and tests for XSS, SQL injection, CSRF, and more
  • Burp Suite Community Edition (free) — intercepting proxy for manual and automated testing

Running OWASP ZAP automated scan:

bash
# Run ZAP in Docker — quick automated scan
docker run -t owasp/zap2docker-stable zap-baseline.py \\
  -t https://yourapp.com \\
  -r zap-report.html

SSL/TLS deep scan

bash
# Check TLS configuration details
# Or use the web interface at ssllabs.com/ssltest

Run your domain through Qualys SSL Labs for a detailed TLS grade. Check for deprecated protocols (TLS 1.0, 1.1), weak ciphers, and certificate chain issues.


Step 3: Manual Security Checks

Automated tools have blind spots. Manual checks cover authentication logic, authorization enforcement, and application-specific vulnerabilities.

Authentication

  • [ ] Test password reset flow: does it use time-limited tokens? Does it invalidate old tokens?
  • [ ] Test account lockout: is there brute force protection on the login endpoint?
  • [ ] Check for username enumeration: does the app respond differently to valid vs invalid usernames?
  • [ ] Test session invalidation on logout: is the server-side session actually destroyed?
  • [ ] Check for concurrent session handling: can the same account be logged in from multiple sessions?

Authorization

  • [ ] Test Insecure Direct Object References (IDOR): can you access /api/users/123 when you are user 456?
  • [ ] Test privilege escalation: can a regular user perform admin actions by modifying request parameters?
  • [ ] Check API endpoints for missing authentication middleware: try hitting API routes without a token
bash
# Quick IDOR test
curl -H "Authorization: Bearer [user-A-token]" \\
  https://api.yourdomain.com/api/invoices/[user-B-invoice-id]

# Should return 403 Forbidden, not the invoice data

Input validation

  • [ ] Test for reflected XSS in search fields and URL parameters
  • [ ] Test for stored XSS in user profile fields, comments, or any user-controlled content
  • [ ] Check file upload handling: can you upload a PHP or HTML file? Are file types validated server-side?
  • [ ] Test for open redirects in ?redirect=, ?return=, or ?url= parameters

Security headers (manual verification)

bash
curl -I https://yourdomain.com 2>/dev/null | grep -i \\
  -e "content-security-policy" \\
  -e "strict-transport-security" \\
  -e "x-frame-options" \\
  -e "x-content-type-options" \\
  -e "referrer-policy" \\
  -e "permissions-policy"

Step 4: Code Review

Manual code review focuses on patterns that automated scanners miss because they require understanding context.

What to look for

Authentication and session management:

js
// Look for session tokens that are too short or predictable
const sessionId = Math.random().toString(36);   // WRONG — predictable
const sessionId = crypto.randomBytes(32).toString("hex");   // Correct

SQL injection risk:

js
// Look for string interpolation in database queries
const query = `SELECT * FROM users WHERE id = ${userId}`;   // WRONG — SQL injection risk
const query = "SELECT * FROM users WHERE id = $1";          // Correct — parameterized

Sensitive data in logs:

js
// Look for credentials or tokens being logged
console.log("Login attempt:", email, password);   // WRONG — logs passwords
console.log("Login attempt for:", email);         // Correct

Hardcoded secrets:

js
// Look for these patterns
const apiKey = "sk-live-abc123";                  // Hardcoded secret
const stripeKey = process.env.STRIPE_SECRET_KEY;  // Correct

Code review tools

  • Semgrep (free, open source) — static analysis with security-focused rules
  • ESLint with security plugins — eslint-plugin-security, eslint-plugin-no-secrets
bash
# Run semgrep with the security ruleset
semgrep --config=p/security-audit --output=semgrep-report.json .

Step 5: Dependency Audit

Third-party dependencies are a major attack vector. The Log4Shell vulnerability in 2021 and the event-stream incident are examples of how a single dependency compromise can affect thousands of applications.

Node.js

bash
npm audit --json > audit-report.json

# Get a summary
npm audit 2>&1 | tail -5

Python

bash
pip install pip-audit
pip-audit --output=json > audit-report.json

Ruby

bash
gem install bundler-audit
bundle-audit check --update

PHP (Composer)

bash
composer audit

Prioritizing dependency findings

SeverityAction
CriticalFix immediately — check if you are using the vulnerable function/feature
HighFix within 48 hours
ModerateFix in next sprint
LowFix when convenient, or accept risk with documentation

Important: Not every npm audit finding is an active risk in your application. A high-severity vulnerability in a server-side CLI tool that never processes user input may not be exploitable in your context. Review the advisory to understand the attack vector.


Step 6: Reporting

A security audit is only as useful as the action it generates. Create a structured report with enough information for each finding to be reproduced, understood, and fixed.

Report structure

Executive Summary - Security score (use ZeriFlow''s /100 as a baseline) - Number of findings by severity - Top 3 most critical issues

Findings Table

IDTitleSeverityStatusOwner
SEC-001Missing HSTS headerHighOpenBackend team
SEC-002Session cookie missing SameSiteMediumOpenAuth service
SEC-003npm lodash vulnerability CVE-XXXXHighOpenFrontend team

Detailed Finding Format

For each finding: - Title: Short descriptive name - Severity: Critical / High / Medium / Low / Informational - Description: What the vulnerability is and why it matters - Evidence: Screenshot, curl command output, or code snippet showing the issue - Reproduction steps: Exact steps to reproduce - Remediation: Specific fix with code example if relevant - References: CVE number, OWASP page, or documentation link

Severity rating guide

Use CVSS scores or this simplified guide:

SeverityCriteria
CriticalDirect data breach, account takeover, RCE possible
HighSignificant business impact, exploitable with moderate effort
MediumLimited impact or requires specific conditions
LowDefense-in-depth improvement, unlikely to be exploited alone
InformationalBest practice recommendation

Step 7: Remediation Tracking

A finding without a ticket is a finding that will not be fixed. Every finding in your report should have: - A GitHub issue, Jira ticket, or Linear ticket - Assigned owner - Target resolution date based on severity - A way to verify the fix when deployed

Suggested SLAs

SeverityFix timeline
Critical24 hours
High1 week
Medium1 sprint (2 weeks)
LowNext quarter

Verification

After deploying a fix, re-run the specific test that identified the vulnerability. For header and configuration issues, re-run the ZeriFlow scan and check that the finding is resolved. For code-level fixes, re-run Semgrep or the relevant test.

Track your overall security score over time. A quarterly ZeriFlow scan gives you a consistent, comparable number.


PhaseTools
Scope definitionGoogle Docs, Notion, Confluence
Automated scanningZeriFlow (free), OWASP ZAP, Qualys SSL Labs
Manual testingBurp Suite Community, browser DevTools, curl
Code reviewSemgrep, GitHub Advanced Security, ESLint security plugins
Dependency auditnpm audit, pip-audit, bundler-audit
ReportingGoogle Docs, Notion, Jira, GitHub Issues
Remediation trackingJira, Linear, GitHub Projects

Running Your First Audit in One Day

A focused first audit on a medium-sized application can be completed in one working day:

  • Morning (2–3 hours): Define scope, run ZeriFlow scan, run SSL Labs, run OWASP ZAP
  • Midday (2–3 hours): Manual authentication and authorization testing, code review for hardcoded secrets and SQL queries
  • Afternoon (2–3 hours): Dependency audit, report writing, ticket creation

The output is a structured report with a prioritized fix list and a security score you can use to measure improvement.

Run a free scan at zeriflow.com/free-scan to start step 2 right now.


Summary

A website security audit follows a repeatable 7-step process: scope definition, automated scanning, manual security checks, code review, dependency audit, reporting, and remediation tracking. Start with automated tools to surface the majority of common vulnerabilities quickly, then apply manual testing to cover logic flaws and authorization bypasses that tools miss. Document findings with enough detail to be reproduced and fixed, assign owners, set SLA-based deadlines, and track your security score over time to demonstrate improvement.

Ready to check your site?

Run a free security scan in 30 seconds.

Related articles

Keep reading