OWASP ZAP คู่มือฉบับสมบูรณ์ 2026
OWASP ZAP (Zed Attack Proxy) เป็น open source web application security scanner ที่ได้รับความนิยมสูงสุดในโลก พัฒนาโดย OWASP Foundation ใช้สำหรับค้นหา vulnerabilities ในเว็บแอปพลิเคชันทั้งแบบ manual testing และ automated scanning รองรับทั้ง DAST (Dynamic Application Security Testing) และ API scanning ZAP เหมาะสำหรับ security testers, developers และ DevSecOps teams ที่ต้องการเครื่องมือ security testing ฟรีและมีคุณภาพระดับ enterprise
ZAP Installation & Setup
# zap_setup.py — OWASP ZAP installation and setup
import json
class ZAPSetup:
INSTALL_METHODS = {
"desktop": {
"name": "Desktop Application",
"platforms": "Windows, macOS, Linux",
"download": "https://www.zaproxy.org/download/",
"requirement": "Java 11+ (bundled in installer)",
},
"docker": {
"name": "Docker",
"command": "docker pull zaproxy/zap-stable",
"variants": ["zap-stable (weekly updates)", "zap-bare (minimal)", "zap-full (all add-ons)"],
},
"cli": {
"name": "Command Line (Headless)",
"command": "docker run -t zaproxy/zap-stable zap-baseline.py -t https://example.com",
"use": "CI/CD pipelines, automated scanning",
},
}
SCAN_TYPES = {
"baseline": {
"name": "Baseline Scan",
"description": "Quick passive scan — ไม่ส่ง attack requests",
"duration": "1-5 minutes",
"command": "zap-baseline.py -t https://example.com",
"use": "CI/CD pipeline, quick check",
},
"full": {
"name": "Full Scan",
"description": "Passive + Active scan — ส่ง attack requests ทดสอบ vulns",
"duration": "10 minutes - 2+ hours",
"command": "zap-full-scan.py -t https://example.com",
"use": "Comprehensive security testing",
},
"api": {
"name": "API Scan",
"description": "สแกน APIs จาก OpenAPI/Swagger spec",
"duration": "5-30 minutes",
"command": "zap-api-scan.py -t https://example.com/openapi.json -f openapi",
"use": "API security testing",
},
}
def show_install(self):
print("=== Installation Methods ===\n")
for key, method in self.INSTALL_METHODS.items():
print(f"[{method['name']}]")
if "command" in method:
print(f" Command: {method['command']}")
if "platforms" in method:
print(f" Platforms: {method['platforms']}")
print()
def show_scans(self):
print("=== Scan Types ===")
for key, scan in self.SCAN_TYPES.items():
print(f" [{scan['name']}] {scan['description']}")
print(f" Duration: {scan['duration']} | Command: {scan['command']}")
print()
setup = ZAPSetup()
setup.show_install()
setup.show_scans()
Automated Scanning
# automated.py — ZAP automated scanning
import json
class ZAPAutomated:
PYTHON_API = """
# zap_scanner.py — ZAP Python API client
from zapv2 import ZAPv2
import time
class ZAPScanner:
def __init__(self, target, api_key='changeme', proxy='http://localhost:8080'):
self.target = target
self.zap = ZAPv2(apikey=api_key, proxies={'http': proxy, 'https': proxy})
def spider(self):
print(f"Spidering {self.target}...")
scan_id = self.zap.spider.scan(self.target)
while int(self.zap.spider.status(scan_id)) < 100:
print(f" Spider progress: {self.zap.spider.status(scan_id)}%")
time.sleep(5)
print(f" Spider complete. URLs found: {len(self.zap.spider.results(scan_id))}")
def passive_scan(self):
print("Waiting for passive scan...")
while int(self.zap.pscan.records_to_scan) > 0:
print(f" Records to scan: {self.zap.pscan.records_to_scan}")
time.sleep(2)
print(" Passive scan complete.")
def active_scan(self):
print(f"Active scanning {self.target}...")
scan_id = self.zap.ascan.scan(self.target)
while int(self.zap.ascan.status(scan_id)) < 100:
print(f" Active scan progress: {self.zap.ascan.status(scan_id)}%")
time.sleep(10)
print(" Active scan complete.")
def get_alerts(self):
alerts = self.zap.core.alerts(baseurl=self.target)
summary = {}
for alert in alerts:
risk = alert.get('risk', 'Informational')
summary[risk] = summary.get(risk, 0) + 1
print(f"\\nAlerts Summary:")
for risk in ['High', 'Medium', 'Low', 'Informational']:
count = summary.get(risk, 0)
print(f" [{risk}]: {count}")
return alerts
def generate_report(self, filename='zap_report.html'):
report = self.zap.core.htmlreport()
with open(filename, 'w') as f:
f.write(report)
print(f"Report saved: {filename}")
def full_scan(self):
self.spider()
self.passive_scan()
self.active_scan()
alerts = self.get_alerts()
self.generate_report()
return alerts
scanner = ZAPScanner('https://example.com')
scanner.full_scan()
"""
DOCKER_COMMANDS = """
# Docker-based scanning commands
# Baseline scan (quick, passive only)
docker run -t zaproxy/zap-stable zap-baseline.py \\
-t https://example.com \\
-r report.html
# Full scan (passive + active)
docker run -t zaproxy/zap-stable zap-full-scan.py \\
-t https://example.com \\
-r report.html \\
-m 10 # max scan duration in minutes
# API scan (OpenAPI/Swagger)
docker run -t zaproxy/zap-stable zap-api-scan.py \\
-t https://example.com/openapi.json \\
-f openapi \\
-r api-report.html
# With authentication
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable \\
zap-full-scan.py -t https://example.com \\
-r report.html \\
--hook=/zap/wrk/auth_hook.py
"""
def show_api(self):
print("=== Python API ===")
print(self.PYTHON_API[:600])
def show_docker(self):
print(f"\n=== Docker Commands ===")
print(self.DOCKER_COMMANDS[:500])
auto = ZAPAutomated()
auto.show_api()
auto.show_docker()
CI/CD Integration
# cicd.py — ZAP in CI/CD pipelines
import json
class ZAPCICD:
GITHUB_ACTION = """
# .github/workflows/zap-scan.yml
name: OWASP ZAP Scan
on:
schedule:
- cron: '0 3 * * 1' # Weekly Monday 3 AM
workflow_dispatch:
jobs:
zap-baseline:
runs-on: ubuntu-latest
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'https://example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
- name: Upload Report
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-report
path: report_html.html
zap-full:
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
steps:
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.10.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
zap-api:
runs-on: ubuntu-latest
steps:
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.7.0
with:
target: 'https://api.example.com/openapi.json'
format: openapi
"""
RULES_FILE = """
# .zap/rules.tsv — Custom alert rules
# Format: rule_id action name
10021 IGNORE X-Content-Type-Options Header Missing
10038 WARN Content Security Policy (CSP) Header Not Set
40012 FAIL Cross Site Scripting (Reflected)
40014 FAIL Cross Site Scripting (Persistent)
40018 FAIL SQL Injection
90001 WARN Insecure JSF ViewState
"""
def show_github(self):
print("=== GitHub Actions ===")
print(self.GITHUB_ACTION[:600])
def show_rules(self):
print(f"\n=== Custom Rules ===")
print(self.RULES_FILE[:400])
cicd = ZAPCICD()
cicd.show_github()
cicd.show_rules()
Common Vulnerabilities Found
# vulns.py — Common vulnerabilities ZAP finds
import json
import random
class ZAPFindings:
COMMON_VULNS = {
"xss": {
"name": "Cross-Site Scripting (XSS)",
"risk": "High",
"owasp": "A03:2021 Injection",
"fix": "Encode output, use CSP headers, validate input",
},
"sqli": {
"name": "SQL Injection",
"risk": "High",
"owasp": "A03:2021 Injection",
"fix": "Use parameterized queries, ORM, input validation",
},
"csrf": {
"name": "Cross-Site Request Forgery (CSRF)",
"risk": "Medium",
"owasp": "A01:2021 Broken Access Control",
"fix": "Anti-CSRF tokens, SameSite cookies",
},
"missing_headers": {
"name": "Missing Security Headers",
"risk": "Low-Medium",
"owasp": "A05:2021 Security Misconfiguration",
"fix": "Add CSP, X-Frame-Options, X-Content-Type-Options, HSTS",
},
"ssl_issues": {
"name": "SSL/TLS Issues",
"risk": "Medium",
"owasp": "A02:2021 Cryptographic Failures",
"fix": "Use TLS 1.2+, strong ciphers, HSTS",
},
"info_disclosure": {
"name": "Information Disclosure",
"risk": "Low",
"owasp": "A05:2021 Security Misconfiguration",
"fix": "Remove server headers, error details, debug info",
},
}
def show_vulns(self):
print("=== Common Vulnerabilities ===\n")
for key, vuln in self.COMMON_VULNS.items():
print(f"[{vuln['risk']:>6}] {vuln['name']}")
print(f" OWASP: {vuln['owasp']}")
print(f" Fix: {vuln['fix']}")
print()
def simulate_scan(self):
print("=== Simulated Scan Results ===")
results = {
"High": random.randint(0, 5),
"Medium": random.randint(2, 15),
"Low": random.randint(5, 30),
"Informational": random.randint(10, 50),
}
total = sum(results.values())
for risk, count in results.items():
bar = "█" * (count // 2)
print(f" [{risk:>15}] {count:>3} {bar}")
print(f" {'Total':>16} {total:>3}")
vulns = ZAPFindings()
vulns.show_vulns()
vulns.simulate_scan()
Authentication & Advanced
# advanced.py — ZAP authentication and advanced features
import json
class ZAPAdvanced:
AUTH_METHODS = {
"form_based": {
"name": "Form-Based Authentication",
"description": "Login ผ่าน HTML form (username/password)",
"setup": "Context → Authentication → Form-based → กำหนด login URL + fields",
},
"json_based": {
"name": "JSON/API Authentication",
"description": "Login ผ่าน API endpoint (POST JSON)",
"setup": "Context → Authentication → JSON-based → กำหนด API URL + body",
},
"script_based": {
"name": "Script-Based Authentication",
"description": "Custom authentication logic ด้วย script",
"setup": "Scripts → Authentication → เขียน custom auth script",
},
"header_based": {
"name": "Header-Based (API Key/Bearer Token)",
"description": "ส่ง token ใน HTTP header ทุก request",
"setup": "Replacer add-on → Add header Authorization: Bearer ",
},
}
AUTOMATION_FRAMEWORK = """
# automation.yaml — ZAP Automation Framework
env:
contexts:
- name: "My App"
urls:
- "https://example.com"
includePaths:
- "https://example.com/.*"
excludePaths:
- "https://example.com/logout.*"
authentication:
method: "form"
parameters:
loginUrl: "https://example.com/login"
loginRequestData: "username={%username%}&password={%password%}"
verification:
method: "response"
loggedInRegex: "Welcome"
users:
- name: "testuser"
credentials:
username: "test@example.com"
password: "testpass123"
jobs:
- type: spider
parameters:
context: "My App"
user: "testuser"
maxDuration: 5
- type: spiderAjax
parameters:
context: "My App"
maxDuration: 5
- type: passiveScan-wait
parameters:
maxDuration: 10
- type: activeScan
parameters:
context: "My App"
maxScanDuration: 30
- type: report
parameters:
template: "traditional-html"
reportDir: "/zap/wrk/"
reportFile: "report.html"
"""
def show_auth(self):
print("=== Authentication Methods ===\n")
for key, auth in self.AUTH_METHODS.items():
print(f"[{auth['name']}]")
print(f" {auth['description']}")
print()
def show_automation(self):
print("=== Automation Framework ===")
print(self.AUTOMATION_FRAMEWORK[:500])
adv = ZAPAdvanced()
adv.show_auth()
adv.show_automation()
FAQ - คำถามที่พบบ่อย
Q: ZAP กับ Burp Suite อันไหนดี?
A: ZAP: ฟรี open source, ดีสำหรับ automated scanning, CI/CD integration ง่าย Burp Suite Pro: $449/year, manual testing features ดีกว่า, extensions เยอะ ใช้ ZAP: automated DAST ใน CI/CD, budget จำกัด, team ใหญ่ ใช้ Burp: manual penetration testing, advanced features หลายทีมใช้ทั้งคู่: ZAP สำหรับ automated CI/CD + Burp สำหรับ manual testing
Q: สแกน production ปลอดภัยไหม?
A: Baseline scan (passive): ปลอดภัย ไม่ส่ง attack requests Full/Active scan: มีความเสี่ยง อาจสร้าง junk data, trigger alerts, affect performance แนะนำ: Active scan บน staging เท่านั้น ใช้ Baseline scan สำหรับ production ถ้าต้อง active scan production: ทำนอกเวลา peak, แจ้ง ops team
Q: ZAP หา vulnerabilities ได้ครบไหม?
A: ไม่ครบ 100% — ไม่มี scanner ตัวไหนหาได้ครบ ZAP เก่งเรื่อง: XSS, SQLi, CSRF, misconfigurations, info disclosure ZAP ไม่เก่ง: business logic flaws, authentication bypass, complex auth flows ใช้ ZAP + manual testing + SAST (Semgrep/Snyk) = coverage ดีขึ้น
Q: Scan ใช้เวลานานแค่ไหน?
A: Baseline (passive): 1-5 นาที Full scan (small site): 10-30 นาที Full scan (large site): 1-4+ ชั่วโมง API scan: 5-30 นาที ขึ้นอยู่กับ: จำนวน URLs, complexity, server response time ตั้ง max duration เพื่อ limit ใน CI/CD
