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.
Anay Pandya
1,720 words
Anay Pandya
Founder of ZeriFlow · 10 years fullstack engineering · About the author
Key Takeaways
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.
Is your site actually secure?
Run a free check — 60 seconds
Keep reading
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.
Before running any tools, define what you are auditing. This prevents scope creep, focuses your effort, and creates a document trail.
Write this down. A one-page scope document is enough and becomes part of your audit report.
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.
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.
For a deeper automated scan that tests the running application, use:
Running OWASP ZAP automated scan:
# Run ZAP in Docker — quick automated scan
docker run -t owasp/zap2docker-stable zap-baseline.py \\
-t https://yourapp.com \\
-r zap-report.html# Check TLS configuration details
# Or use the web interface at ssllabs.com/ssltestRun 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.
Automated tools have blind spots. Manual checks cover authentication logic, authorization enforcement, and application-specific vulnerabilities.
/api/users/123 when you are user 456?# 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?redirect=, ?return=, or ?url= parameterscurl -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"Manual code review focuses on patterns that automated scanners miss because they require understanding context.
Authentication and session management:
// 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"); // CorrectSQL injection risk:
// 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 — parameterizedSensitive data in logs:
// Look for credentials or tokens being logged
console.log("Login attempt:", email, password); // WRONG — logs passwords
console.log("Login attempt for:", email); // CorrectHardcoded secrets:
// Look for these patterns
const apiKey = "sk-live-abc123"; // Hardcoded secret
const stripeKey = process.env.STRIPE_SECRET_KEY; // Correct# Run semgrep with the security ruleset
semgrep --config=p/security-audit --output=semgrep-report.json .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.
npm audit --json > audit-report.json
# Get a summary
npm audit 2>&1 | tail -5pip install pip-audit
pip-audit --output=json > audit-report.jsongem install bundler-audit
bundle-audit check --updatecomposer audit| Severity | Action |
|---|---|
| Critical | Fix immediately — check if you are using the vulnerable function/feature |
| High | Fix within 48 hours |
| Moderate | Fix in next sprint |
| Low | Fix 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.
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.
Executive Summary - Security score (use ZeriFlow''s /100 as a baseline) - Number of findings by severity - Top 3 most critical issues
Findings Table
| ID | Title | Severity | Status | Owner |
|---|---|---|---|---|
| SEC-001 | Missing HSTS header | High | Open | Backend team |
| SEC-002 | Session cookie missing SameSite | Medium | Open | Auth service |
| SEC-003 | npm lodash vulnerability CVE-XXXX | High | Open | Frontend 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
Use CVSS scores or this simplified guide:
| Severity | Criteria |
|---|---|
| Critical | Direct data breach, account takeover, RCE possible |
| High | Significant business impact, exploitable with moderate effort |
| Medium | Limited impact or requires specific conditions |
| Low | Defense-in-depth improvement, unlikely to be exploited alone |
| Informational | Best practice recommendation |
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
| Severity | Fix timeline |
|---|---|
| Critical | 24 hours |
| High | 1 week |
| Medium | 1 sprint (2 weeks) |
| Low | Next quarter |
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.
| Phase | Tools |
|---|---|
| Scope definition | Google Docs, Notion, Confluence |
| Automated scanning | ZeriFlow (free), OWASP ZAP, Qualys SSL Labs |
| Manual testing | Burp Suite Community, browser DevTools, curl |
| Code review | Semgrep, GitHub Advanced Security, ESLint security plugins |
| Dependency audit | npm audit, pip-audit, bundler-audit |
| Reporting | Google Docs, Notion, Jira, GitHub Issues |
| Remediation tracking | Jira, Linear, GitHub Projects |
A focused first audit on a medium-sized application can be completed in one working day:
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.
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.
Related resources
Website Vulnerability Scanner
Run a broader website security audit across headers, TLS, DNS, cookies, SEO, and disclosure checks.
Security Headers Checker
Check CSP, HSTS, X-Frame-Options, and other response headers.
SSL Checker
Review TLS certificate, HTTPS, and transport security signals.
DMARC Checker
Validate email authentication records for domain spoofing protection.
CSP Checker
Review Content-Security-Policy coverage and common gaps.
April 30, 2026
Best SAST Tools for Small Development Teams in 2026 (Free Included)
Monitor your security score
Schedule recurring scans and catch regressions after deployments.